From e41bc9fc58b02b6c6029ddae186652d0d69fcf40 Mon Sep 17 00:00:00 2001 From: Bert Blommers Date: Thu, 28 Nov 2019 13:22:20 +0000 Subject: [PATCH] DynamoDB - DELETE item from nested sets --- moto/dynamodb2/models.py | 10 +++++-- .../test_dynamodb_table_with_range_key.py | 28 ++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/moto/dynamodb2/models.py b/moto/dynamodb2/models.py index e3ba1b3ee..fa8d45294 100644 --- a/moto/dynamodb2/models.py +++ b/moto/dynamodb2/models.py @@ -420,12 +420,18 @@ class Item(BaseModel): if not dyn_value.is_set(): raise TypeError - existing = self.attrs.get(key, None) + key_head = key.split(".")[0] + key_tail = ".".join(key.split(".")[1:]) + existing = self.attrs.get(key_head) + existing = existing.get(key_tail) if existing: if not existing.same_type(dyn_value): raise TypeError new_set = set(existing.value).difference(dyn_value.value) - self.attrs[key] = DynamoType({existing.type: list(new_set)}) + existing.set( + key=None, + new_value=DynamoType({existing.type: list(new_set)}), + ) else: raise NotImplementedError( "{} update action not yet supported".format(action) diff --git a/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py b/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py index f99177ee8..7c7770874 100644 --- a/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py +++ b/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py @@ -1347,7 +1347,7 @@ def test_update_item_add_with_expression(): @mock_dynamodb2 -def test_update_item_add_with_nested_sets_and_expression_names(): +def test_update_item_add_with_nested_sets(): table = _create_table_with_range_key() item_key = {"forum_name": "the-key", "subject": "123"} @@ -1383,6 +1383,32 @@ def test_update_item_add_with_nested_sets_and_expression_names(): dict(table.get_item(Key=item_key)["Item"]).should.equal(current_item) +@mock_dynamodb2 +def test_update_item_delete_with_nested_sets(): + table = _create_table_with_range_key() + + item_key = {"forum_name": "the-key", "subject": "123"} + current_item = { + "forum_name": "the-key", + "subject": "123", + "nested": {"str_set": {"item1", "item2", "item3"}}, + } + + # Put an entry in the DB to play with + table.put_item(Item=current_item) + + # Update item to add a string value to a nested string set + table.update_item( + Key=item_key, + UpdateExpression="DELETE nested.str_set :v", + ExpressionAttributeValues={":v": {"item3"}}, + ) + current_item["nested"]["str_set"] = current_item["nested"]["str_set"].difference( + {"item3"} + ) + dict(table.get_item(Key=item_key)["Item"]).should.equal(current_item) + + @mock_dynamodb2 def test_update_item_delete_with_expression(): table = _create_table_with_range_key()