Fix DynamoDB UpdateExpression support for REMOVE on nested maps

This commit is contained in:
Ber Zoidberg 2019-06-11 22:38:15 -07:00
parent df493ea18d
commit 96c2506fd4
2 changed files with 52 additions and 0 deletions

View File

@ -149,6 +149,29 @@ class Item(BaseModel):
value = re.sub(r'{0}\b'.format(k), v, value)
if action == "REMOVE":
key = value
if '.' not in key:
self.attrs.pop(value, None)
else:
# Handle nested dict updates
key_parts = key.split('.')
attr = key_parts.pop(0)
if attr not in self.attrs:
raise ValueError
last_val = self.attrs[attr].value
for key_part in key_parts[:-1]:
# Hack but it'll do, traverses into a dict
last_val_type = list(last_val.keys())
if last_val_type and last_val_type[0] == 'M':
last_val = last_val['M']
if key_part not in last_val:
last_val[key_part] = {'M': {}}
last_val = last_val[key_part]
last_val.pop(key_parts[-1], None)
self.attrs.pop(value, None)
elif action == 'SET':
key, value = value.split("=", 1)

View File

@ -450,6 +450,35 @@ def test_update_item_remove():
})
@mock_dynamodb2_deprecated
def test_update_item_nested_remove():
conn = boto.dynamodb2.connect_to_region("us-east-1")
table = Table.create('messages', schema=[
HashKey('username')
])
data = {
'username': "steve",
'Meta': {
'FullName': 'Steve Urkel'
}
}
table.put_item(data=data)
key_map = {
'username': {"S": "steve"}
}
# Then remove the SentBy field
conn.update_item("messages", key_map,
update_expression="REMOVE Meta.FullName")
returned_item = table.get_item(username="steve")
dict(returned_item).should.equal({
'username': "steve",
'Meta': {}
})
@mock_dynamodb2_deprecated
def test_update_item_set():
conn = boto.dynamodb2.connect_to_region("us-east-1")