From 88cd009c4d9d3f046ba9c240de11511db9f13fca Mon Sep 17 00:00:00 2001 From: Paul Craciunoiu Date: Thu, 14 Jan 2016 15:46:05 -0700 Subject: [PATCH] Return Item even when item is not found. --- moto/dynamodb2/models.py | 22 +++++++++++- .../test_dynamodb_table_with_range_key.py | 35 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/moto/dynamodb2/models.py b/moto/dynamodb2/models.py index 77b1434c3..950b0cf1d 100644 --- a/moto/dynamodb2/models.py +++ b/moto/dynamodb2/models.py @@ -275,8 +275,11 @@ class Table(object): try: if range_key: return self.items[hash_key][range_key] - else: + + if hash_key in self.items: return self.items[hash_key] + + raise KeyError except KeyError: return None @@ -525,6 +528,23 @@ class DynamoDBBackend(BaseBackend): range_value = None item = table.get_item(hash_value, range_value) + # Update does not fail on new items, so create one + if item is None: + data = { + table.hash_key_attr: { + hash_value.type: hash_value.value, + }, + } + if range_value: + data.update({ + table.range_key_attr: { + range_value.type: range_value.value, + } + }) + + table.put_item(data) + item = table.get_item(hash_value, range_value) + if update_expression: item.update(update_expression) else: 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 a90f06caf..4346a85bf 100644 --- a/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py +++ b/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py @@ -853,6 +853,41 @@ def test_update_item_range_key_set(): }) + +@mock_dynamodb2 +def test_update_item_does_not_exist_is_created(): + table = _create_table_with_range_key() + + item_key = {'forum_name': 'the-key', 'subject': '123'} + table.update_item( + Key=item_key, + AttributeUpdates={ + 'username': { + 'Action': u'PUT', + 'Value': 'johndoe2' + }, + 'created': { + 'Action': u'PUT', + 'Value': Decimal('4'), + }, + 'mapfield': { + 'Action': u'PUT', + 'Value': {'key': 'value'}, + } + }, + ) + + returned_item = dict((k, str(v) if isinstance(v, Decimal) else v) + for k, v in table.get_item(Key=item_key)['Item'].items()) + dict(returned_item).should.equal({ + 'username': "johndoe2", + 'forum_name': 'the-key', + 'subject': '123', + 'created': '4', + 'mapfield': {'key': 'value'}, + }) + + @mock_dynamodb2 def test_boto3_query_gsi_range_comparison(): table = _create_table_with_range_key()