diff --git a/moto/dynamodb2/models/__init__.py b/moto/dynamodb2/models/__init__.py index 782ddcee9..6b3583010 100644 --- a/moto/dynamodb2/models/__init__.py +++ b/moto/dynamodb2/models/__init__.py @@ -109,7 +109,10 @@ class Item(BaseModel): def update_with_attribute_updates(self, attribute_updates): for attribute_name, update_action in attribute_updates.items(): - action = update_action["Action"] + # Use default Action value, if no explicit Action is passed. + # Default value is 'Put', according to + # Boto3 DynamoDB.Client.update_item documentation. + action = update_action.get("Action", "PUT") if action == "DELETE" and "Value" not in update_action: if attribute_name in self.attrs: del self.attrs[attribute_name] diff --git a/tests/test_dynamodb2/test_dynamodb.py b/tests/test_dynamodb2/test_dynamodb.py index 7a2ed32cb..de9811df6 100644 --- a/tests/test_dynamodb2/test_dynamodb.py +++ b/tests/test_dynamodb2/test_dynamodb.py @@ -2251,6 +2251,30 @@ def test_update_item_with_list(): resp["Item"].should.equal({"key": "the-key", "list": [1, 2]}) +# https://github.com/spulec/moto/issues/2328 +@mock_dynamodb2 +def test_update_item_with_no_action_passed_with_list(): + dynamodb = boto3.resource("dynamodb", region_name="us-east-1") + + # Create the DynamoDB table. + dynamodb.create_table( + TableName="Table", + KeySchema=[{"AttributeName": "key", "KeyType": "HASH"}], + AttributeDefinitions=[{"AttributeName": "key", "AttributeType": "S"}], + ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1}, + ) + table = dynamodb.Table("Table") + table.update_item( + Key={"key": "the-key"}, + # Do not pass 'Action' key, in order to check that the + # parameter's default value will be used. + AttributeUpdates={"list": {"Value": [1, 2]}}, + ) + + resp = table.get_item(Key={"key": "the-key"}) + resp["Item"].should.equal({"key": "the-key", "list": [1, 2]}) + + # https://github.com/spulec/moto/issues/1342 @mock_dynamodb2 def test_update_item_on_map():