Skip to content

Commit e87a9dc

Browse files
jmphillidanielhochman
authored andcommitted
allow unstructured map attributes (#186)
1 parent 97321d1 commit e87a9dc

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

pynamodb/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@ def _serialize(self, attr_map=False, null_check=True):
12031203
continue
12041204
elif null_check:
12051205
raise ValueError("Attribute '{0}' cannot be None".format(attr.attr_name))
1206-
if isinstance(attr, MapAttribute):
1206+
if isinstance(value, MapAttribute):
12071207
if not value.validate():
12081208
raise ValueError("Attribute '{0}' is not correctly typed".format(attr.attr_name))
12091209
value = value.get_values()

pynamodb/tests/test_model.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,13 @@ class Meta:
396396
right = TreeLeaf()
397397

398398

399+
class ExplicitRawMapModel(Model):
400+
class Meta:
401+
table_name = 'ExplicitRawMapModel'
402+
403+
map_attr = MapAttribute()
404+
405+
399406
class OverriddenSession(requests.Session):
400407
"""
401408
A overridden session for test
@@ -2996,3 +3003,51 @@ def test_result_set_iter(self):
29963003
rs = ResultSet(results=results, operation=operations, arguments=arguments)
29973004
for k in rs:
29983005
self.assertTrue(k in results)
3006+
3007+
def test_explicit_raw_map_serialize_pass(self):
3008+
map_native = {'foo': 'bar'}
3009+
map_serialized = {'M': {'foo': {'S': 'bar'}}}
3010+
instance = ExplicitRawMapModel(map_attr=map_native)
3011+
serialized = instance._serialize()
3012+
self.assertEqual(serialized['attributes']['map_attr'], map_serialized)
3013+
3014+
def test_raw_map_serialize_fun_one(self):
3015+
map_native = {
3016+
'foo': 'bar', 'num': 1, 'bool_type': True,
3017+
'other_b_type': False, 'floaty': 1.2, 'listy': [1,2,3],
3018+
'mapy': {'baz': 'bongo'}
3019+
}
3020+
expected = {'M': {'foo': {'S': u'bar'},
3021+
'listy': {'L': [{'N': '1'}, {'N': '2'}, {'N': '3'}]},
3022+
'num': {'N': '1'}, 'other_b_type': {'BOOL': False},
3023+
'floaty': {'N': '1.2'}, 'mapy': {'M': {'baz': {'S': u'bongo'}}},
3024+
'bool_type': {'BOOL': True}}}
3025+
3026+
instance = ExplicitRawMapModel(map_attr=map_native)
3027+
serialized = instance._serialize()
3028+
actual = serialized['attributes']['map_attr']
3029+
self.assertEqual(expected, actual)
3030+
3031+
def test_raw_map_deserializes(self):
3032+
map_native = {
3033+
'foo': 'bar', 'num': 1, 'bool_type': True,
3034+
'other_b_type': False, 'floaty': 1.2, 'listy': [1, 2, 3],
3035+
'mapy': {'baz': 'bongo'}
3036+
}
3037+
map_serialized = {
3038+
'M': {
3039+
'foo': {'S': 'bar'},
3040+
'num': {'N': 1},
3041+
'bool_type': {'BOOL': True},
3042+
'other_b_type': {'BOOL': False},
3043+
'floaty': {'N': 1.2},
3044+
'listy': {'L': [{'N': 1}, {'N': 2}, {'N': 3}]},
3045+
'mapy': {'M': {'baz': {'S': 'bongo'}}}
3046+
}
3047+
}
3048+
instance = ExplicitRawMapModel(map_attr=map_native)
3049+
instance._deserialize(map_serialized)
3050+
actual = instance.map_attr
3051+
for k,v in six.iteritems(map_native):
3052+
self.assertEqual(v, actual[k])
3053+

0 commit comments

Comments
 (0)