Skip to content

Commit

Permalink
deserialize map attributes correctly (#192)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmphilli authored and danielhochman committed Nov 8, 2016
1 parent ae06940 commit ce741ab
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pynamodb/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ def from_raw_data(cls, data):
attr = cls._get_attributes().get(name, None)
if attr:
deserialized_attr = attr.deserialize(attr.get_value(value))
if isinstance(attr, MapAttribute):
if isinstance(attr, MapAttribute) and not type(attr) == MapAttribute:
deserialized_attr = type(attr)(**deserialized_attr)
kwargs[name] = deserialized_attr
return cls(*args, **kwargs)
Expand Down
47 changes: 47 additions & 0 deletions pynamodb/tests/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1192,3 +1192,50 @@
}
}
}

EXPLICIT_RAW_MAP_MODEL_TABLE_DATA = {
'Table': {
'ItemCount': 0, 'TableName': 'ExplicitRawMapModel',
'ProvisionedThroughput': {
'ReadCapacityUnits': 2,
'WriteCapacityUnits': 2,
'NumberOfDecreasesToday': 0
},
'CreationDateTime': 1391471876.86,
'TableStatus': 'ACTIVE',
'AttributeDefinitions': [
{
'AttributeName': 'map_id',
'AttributeType': 'N'
},
{
'AttributeName': 'map_attr',
'AttributeType': 'M'
}
],
'KeySchema': [
{
'AttributeName': 'map_id', 'KeyType': 'HASH'
}
],
'TableSizeBytes': 0
}
}

EXPLICIT_RAW_MAP_MODEL_ITEM_DATA = {
'Item': {
'map_id': {
'N': '123',
},
'map_attr': {'M': {
'foo': {'S': 'bar'},
'num': {'N': '1'},
'bool_type': {'BOOL': True},
'other_b_type': {'BOOL': False},
'floaty': {'N': '1.2'},
'listy': {'L': [{'N': '1'}, {'N': '2'}, {'N': '3'}]},
'mapy': {'M': {'baz': {'S': 'bongo'}}}
}
}
}
}
36 changes: 34 additions & 2 deletions pynamodb/tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
BOOLEAN_CONVERSION_MODEL_TABLE_DATA,
BOOLEAN_CONVERSION_MODEL_NEW_STYLE_FALSE_ITEM_DATA, BOOLEAN_CONVERSION_MODEL_NEW_STYLE_TRUE_ITEM_DATA,
BOOLEAN_CONVERSION_MODEL_OLD_STYLE_FALSE_ITEM_DATA, BOOLEAN_CONVERSION_MODEL_OLD_STYLE_TRUE_ITEM_DATA,
BOOLEAN_CONVERSION_MODEL_TABLE_DATA_OLD_STYLE, TREE_MODEL_TABLE_DATA, TREE_MODEL_ITEM_DATA
BOOLEAN_CONVERSION_MODEL_TABLE_DATA_OLD_STYLE, TREE_MODEL_TABLE_DATA, TREE_MODEL_ITEM_DATA,
EXPLICIT_RAW_MAP_MODEL_TABLE_DATA, EXPLICIT_RAW_MAP_MODEL_ITEM_DATA
)

if six.PY3:
Expand Down Expand Up @@ -400,7 +401,7 @@ class Meta:
class ExplicitRawMapModel(Model):
class Meta:
table_name = 'ExplicitRawMapModel'

map_id = NumberAttribute(hash_key=True, default=123)
map_attr = MapAttribute()


Expand Down Expand Up @@ -3076,3 +3077,34 @@ def test_raw_map_deserializes(self):
for k,v in six.iteritems(map_native):
self.assertEqual(v, actual[k])

def test_raw_map_from_raw_data_works(self):
map_native = {
'foo': 'bar', 'num': 1, 'bool_type': True,
'other_b_type': False, 'floaty': 1.2, 'listy': [1, 2, 3],
'mapy': {'baz': 'bongo'}
}
map_serialized = {

'M': {
'foo': {'S': 'bar'},
'num': {'N': 1},
'bool_type': {'BOOL': True},
'other_b_type': {'BOOL': False},
'floaty': {'N': 1.2},
'listy': {'L': [{'N': 1}, {'N': 2}, {'N': 3}]},
'mapy': {'M': {'baz': {'S': 'bongo'}}}
}
}
instance = ExplicitRawMapModel(map_attr=map_native, map_id=123)
fake_db = self.database_mocker(ExplicitRawMapModel,
EXPLICIT_RAW_MAP_MODEL_TABLE_DATA,
EXPLICIT_RAW_MAP_MODEL_ITEM_DATA,
'map_id', 'N',
'123')
with patch(PATCH_METHOD, new=fake_db) as req:
item = ExplicitRawMapModel.get(123)
actual = item.map_attr
for k, v in six.iteritems(map_native):
self.assertEqual(v, actual[k])


0 comments on commit ce741ab

Please sign in to comment.