3

I am having trouble getting the JSON representation from PynamoDB instance. Here is the Model.

class MyTest(Model):
    """
    Model class representing the Golden table attributes.
    """

    class Meta:
        table_name = "my-test"

    # Query Fields
    Id = UnicodeAttribute(hash_key=True)
    SomeInfo = MapAttribute(default={})
    SomeInfo1 = UnicodeAttribute(null=True)
my_test = MyTest(Id='123', SomeInfo={}, SomeInfo1='testing')

What I need is JSON representation of my_test.

Things I have tried are.

  1. my_test.to_dict() - This gave a non attribute error

  2. json.dumps(my_test.to_dict(), indent=2)

Any help would be appreciated.

Twinkling Star
  • 135
  • 2
  • 14

3 Answers3

4

If you are looking to get a dict out of the pynamoDB model, you can try to use the attribute_values property:

# Define the model
class Car(Model):
    class Meta:
        table_name = "cars"

    # Query Fields
    vin = UnicodeAttribute(hash_key=True)
    make = UnicodeAttribute(null=True)
    model = UnicodeAttribute(null=True)

# Create instance
new_car = Car("123F345", "Honda", "Civic")

# Read back the attributes
attrs = new_car.attribute_values // {"vin": "123F345", "make": "Honda", "model": "Civic"} 

The result in attrs would be plain dict (<class 'dict'>)

Example use case (just for illustration):

// List of dict with the results of a scan of the whole Cars table
results = [car.attribute_values for Cars.scan()]   ​
Dharman
  • 30,962
  • 25
  • 85
  • 135
MA206
  • 91
  • 7
3

PynamoDB recently added to_json and from_json functions to Model object.

However, as of right now, it has some bugs around polymorphic models / attributes, preventing proper deserialization.

I do have a different implementation that supports polymorphic models / attributes. And this one is a little bit more flexible, IMHO.

Lin Yang
  • 41
  • 2
0

So, I had the same problem and the only thing that worked for me was to map each attribute to its specific type and deal with it accordingly, as such:

def __iter__(self):
        for name, attr in self.get_attributes().items():
            if isinstance(attr, MapAttribute):
                if getattr(self, name):
                    yield name, getattr(self, name).as_dict()
            elif isinstance(attr, UTCDateTimeAttribute):
                if getattr(self, name):
                    yield name, attr.serialize(getattr(self, name))
            elif isinstance(attr, NumberAttribute):
                yield name, getattr(self, name)
            else:
                yield name, attr.serialize(getattr(self, name))