From 159e88db531a27c4c96bd90ae3f3b5f64dcff258 Mon Sep 17 00:00:00 2001 From: Ian Auld Date: Thu, 31 Dec 2015 10:17:08 -0800 Subject: [PATCH 1/3] Added test for supporting partial_save --- .../test_dynamodb_table_with_range_key.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) 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 12e3aa15b..6d8ee09c3 100644 --- a/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py +++ b/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py @@ -141,6 +141,36 @@ def test_item_add_and_describe_and_update(): }) +@requires_boto_gte("2.9") +@mock_dynamodb2 +def test_item_partial_save(): + table = create_table() + + data = { + 'forum_name': 'LOLCat Forum', + 'subject': 'The LOLz', + 'Body': 'http://url_to_lolcat.gif', + 'SentBy': 'User A', + } + + table.put_item(data=data) + returned_item = table.get_item(forum_name="LOLCat Forum", subject='The LOLz') + + returned_item['SentBy'] = 'User B' + returned_item.partial_save() + + returned_item = table.get_item( + forum_name='LOLCat Forum', + subject='The LOLz' + ) + dict(returned_item).should.equal({ + 'forum_name': 'LOLCat Forum', + 'subject': 'The LOLz', + 'Body': 'http://url_to_lolcat.gif', + 'SentBy': 'User B', + }) + + @requires_boto_gte("2.9") @mock_dynamodb2 def test_item_put_without_table(): From a0ed89c92d673b5a962e68305a9f04c1a1d7a390 Mon Sep 17 00:00:00 2001 From: Ian Auld Date: Thu, 31 Dec 2015 10:27:01 -0800 Subject: [PATCH 2/3] Added support for partial_save on tables with a hash and range key; Issue #498 --- moto/dynamodb2/models.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/moto/dynamodb2/models.py b/moto/dynamodb2/models.py index 2b1a1b5ee..af67f5091 100644 --- a/moto/dynamodb2/models.py +++ b/moto/dynamodb2/models.py @@ -425,12 +425,17 @@ class DynamoDBBackend(BaseBackend): def update_item(self, table_name, key, update_expression, attribute_updates): table = self.get_table(table_name) - if table.hash_key_attr in key: - # Sometimes the key is wrapped in a dict with the key name - key = key[table.hash_key_attr] + if all([table.hash_key_attr in key, table.range_key_attr in key]): + hash_value = DynamoType(key[table.hash_key_attr]) + range_value = DynamoType(key[table.range_key_attr]) + elif table.hash_key_attr in key: + hash_value = DynamoType(key[table.hash_key_attr]) + range_value = None + else: + hash_value = DynamoType(key) + range_value = None - hash_value = DynamoType(key) - item = table.get_item(hash_value) + item = table.get_item(hash_value, range_value) if update_expression: item.update(update_expression) else: From 33f023fdaf601217dde6b198b65da7d82b292225 Mon Sep 17 00:00:00 2001 From: Ian Auld Date: Thu, 31 Dec 2015 10:46:54 -0800 Subject: [PATCH 3/3] Added comments for clarity --- moto/dynamodb2/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/moto/dynamodb2/models.py b/moto/dynamodb2/models.py index af67f5091..2607d7e89 100644 --- a/moto/dynamodb2/models.py +++ b/moto/dynamodb2/models.py @@ -426,12 +426,15 @@ class DynamoDBBackend(BaseBackend): table = self.get_table(table_name) if all([table.hash_key_attr in key, table.range_key_attr in key]): + # Covers cases where table has hash and range keys, ``key`` param will be a dict hash_value = DynamoType(key[table.hash_key_attr]) range_value = DynamoType(key[table.range_key_attr]) elif table.hash_key_attr in key: + # Covers tables that have a range key where ``key`` param is a dict hash_value = DynamoType(key[table.hash_key_attr]) range_value = None else: + # Covers other cases hash_value = DynamoType(key) range_value = None