Skip to content

Commit 14e2507

Browse files
mathewmarcusjpinner-lyft
authored andcommitted
Ignore unknown attributes during MapAttribute deserialization. Fixes pynamodb#358 (pynamodb#359)
1 parent 6fa5b43 commit 14e2507

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

docs/attributes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,5 @@ These attributes can then be used inside of Model classes just like any other at
192192
class CarInfoMap(MapAttribute):
193193
make = UnicodeAttribute(null=False)
194194
model = UnicodeAttribute(null=True)
195+
196+
`As with a model and its top-level attributes <https://github.com/pynamodb/PynamoDB/blob/master/docs/quickstart.rst#changing-items>`_, a PynamoDB MapAttribute will ignore sub-attributes it does not know about during deserialization. As a result, if the item in DynamoDB contains sub-attributes not declared as properties of the corresponding MapAttribute, save() will cause those sub-attributes to be deleted.

pynamodb/attributes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,8 @@ def deserialize(self, values):
765765
attr_value = _get_value_for_deserialize(v)
766766
key = self._dynamo_to_python_attr(k)
767767
attr_class = self._get_deserialize_class(key, v)
768+
if attr_class is None:
769+
continue
768770
deserialized_value = None
769771
if attr_value is not None:
770772
deserialized_value = attr_class.deserialize(attr_value)

pynamodb/tests/test_attributes.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,23 @@ def test_map_overridden_attrs_serialize(self):
603603
expected = {'number_attr': {'N': '10'}, 'unicode_attr': {'S': six.u('Hello')}}
604604
assert CustomAttrMap().serialize(attribute) == expected
605605

606+
def test_additional_attrs_deserialize(self):
607+
raw_data = {
608+
'number_attr': {
609+
'N': '10'},
610+
'unicode_attr': {
611+
'S': six.u('Hello')
612+
},
613+
'undeclared_attr': {
614+
'S': six.u('Goodbye')
615+
}
616+
}
617+
expected = {
618+
'overridden_number_attr': 10,
619+
'overridden_unicode_attr': "Hello"
620+
}
621+
assert CustomAttrMap().deserialize(raw_data).attribute_values == expected
622+
606623
def test_defaults(self):
607624
item = DefaultsMap()
608625
assert item.validate()

0 commit comments

Comments
 (0)