pynamodb-encoder
provides helper classes that can convert PynamoDB Model
objects into JSON
serializable dict
. It can also decode such dict
back into those Model
objects. Polymorphic models and attributes are also supported.
def test_encode_complex_model(encoder: Encoder):
class Pet(DynamicMapAttribute):
cls = DiscriminatorAttribute()
name = UnicodeAttribute()
class Cat(Pet, discriminator="Cat"):
pass
class Dog(Pet, discriminator="Dog"):
pass
class Human(Model):
name = UnicodeAttribute()
pets = ListAttribute(of=Pet)
jon = Human(name="Jon", pets=[Cat(name="Garfield", age=43), Dog(name="Odie")])
assert encoder.encode(jon) == {
"name": "Jon",
"pets": [{"cls": "Cat", "name": "Garfield", "age": 43}, {"cls": "Dog", "name": "Odie"}],
}
def test_decode_complex_model(decoder: Decoder):
class Pet(DynamicMapAttribute):
cls = DiscriminatorAttribute()
class Cat(Pet, discriminator="Cat"):
name = UnicodeAttribute()
class Dog(Pet, discriminator="Dog"):
breed = UnicodeAttribute()
class Human(Model):
name = UnicodeAttribute()
age = NumberAttribute()
pets = ListAttribute(of=Pet)
jon = decoder.decode(
Human,
{
"name": "Jon",
"age": 70,
"pets": [{"cls": "Cat", "name": "Garfield"}, {"cls": "Dog", "breed": "Terrier"}],
},
)
assert jon.name == "Jon"
assert jon.age == 70
assert isinstance(jon.pets, list)
assert len(jon.pets) == 2
assert isinstance(jon.pets[0], Cat)
assert jon.pets[0].name == "Garfield"
assert isinstance(jon.pets[1], Dog)
assert jon.pets[1].breed == "Terrier"
More examples can be found in encoder_test.py and decoder_test.py