3.4 KiB
Manipulating Data Structures
Colander schemas have some utility functions which can be used to
manipulate an appstruct
or a cstruct
. Nested data structures can be flattened into
a single dictionary or a single flattened dictionary can be used to
produce a nested data structure. Values of particular nodes can also be
set or retrieved based on a flattened path spec.
Flattening a Data Structure
colander.SchemaNode.flatten
can be used to convert a
datastructure with nested dictionaries and/or lists into a single
flattened dictionary where each key in the dictionary is a dotted name
path to the node in the nested structure.
Consider the following schema:
import colander
class Friend(colander.TupleSchema):
= colander.SchemaNode(colander.Int(),
rank =colander.Range(0, 9999))
validator= colander.SchemaNode(colander.String())
name
class Phone(colander.MappingSchema):
= colander.SchemaNode(colander.String(),
location =colander.OneOf(['home', 'work']))
validator= colander.SchemaNode(colander.String())
number
class Friends(colander.SequenceSchema):
= Friend()
friend
class Phones(colander.SequenceSchema):
= Phone()
phone
class Person(colander.MappingSchema):
= colander.SchemaNode(colander.String())
name = colander.SchemaNode(colander.Int(),
age =colander.Range(0, 200))
validator= Friends()
friends = Phones() phones
Consider also a particular serialization of data using that schema:
= {
appstruct 'name':'keith',
'age':20,
'friends':[(1, 'jim'),(2, 'bob'), (3, 'joe'), (4, 'fred')],
'phones':[{'location':'home', 'number':'555-1212'},
'location':'work', 'number':'555-8989'},],
{ }
This data can be flattened:
= Person()
schema = schema.flatten(appstruct) fstruct
The resulting flattened structure would look like this:
{'name': 'keith',
'age': 20,
'friends.0.rank': 1,
'friends.0.name': 'jim',
'friends.1.rank': 2,
'friends.1.name': 'bob',
'friends.2.rank': 3,
'friends.2.name': 'joe',
'friends.3.rank': 4,
'friends.3.name': 'fred',
'phones.0.location': 'home',
'phones.0.number': '555-1212',
'phones.1.location': 'work',
'phones.1.number': '555-8989',
}
The process can be reversed using colandar.SchemaNode.unflatten
:
= schema.unflatten(fstruct) appstruct
Either an appstruct
or a cstruct
can be
flattened or unflattened in this way.
Accessing and Mutating Nodes in a Data Structure
colander.SchemaNode.get_value
and colander.SchemaNode.set_value
can be used to access
and mutate nodes in an appstruct
or cstruct
. Using the example from above:
# How much do I like Joe?
= schema.get_value(appstruct, 'friends.2.rank')
rank
# Joe bought me beer. Let's promote Joe.
'friends.2.rank', rank + 5000) schema.set_value(appstruct,