Validate AST before creating new item (#3754)
This commit is contained in:
parent
34c00e7dbd
commit
4653c34fd5
@ -1407,6 +1407,22 @@ class DynamoDBBackend(BaseBackend):
|
|||||||
|
|
||||||
# Update does not fail on new items, so create one
|
# Update does not fail on new items, so create one
|
||||||
if item is None:
|
if item is None:
|
||||||
|
if update_expression:
|
||||||
|
# Validate AST before creating anything
|
||||||
|
item = Item(
|
||||||
|
hash_value,
|
||||||
|
table.hash_key_type,
|
||||||
|
range_value,
|
||||||
|
table.range_key_type,
|
||||||
|
attrs={},
|
||||||
|
)
|
||||||
|
UpdateExpressionValidator(
|
||||||
|
update_expression_ast,
|
||||||
|
expression_attribute_names=expression_attribute_names,
|
||||||
|
expression_attribute_values=expression_attribute_values,
|
||||||
|
item=item,
|
||||||
|
table=table,
|
||||||
|
).validate()
|
||||||
data = {table.hash_key_attr: {hash_value.type: hash_value.value}}
|
data = {table.hash_key_attr: {hash_value.type: hash_value.value}}
|
||||||
if range_value:
|
if range_value:
|
||||||
data.update(
|
data.update(
|
||||||
|
@ -6245,3 +6245,35 @@ def test_describe_endpoints(region):
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_dynamodb2
|
||||||
|
def test_update_non_existing_item_raises_error_and_does_not_contain_item_afterwards():
|
||||||
|
"""
|
||||||
|
https://github.com/spulec/moto/issues/3729
|
||||||
|
Exception is raised, but item was persisted anyway
|
||||||
|
Happened because we would create a placeholder, before validating/executing the UpdateExpression
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
name = "TestTable"
|
||||||
|
conn = boto3.client("dynamodb", region_name="us-west-2")
|
||||||
|
hkey = "primary_partition_key"
|
||||||
|
conn.create_table(
|
||||||
|
TableName=name,
|
||||||
|
KeySchema=[{"AttributeName": hkey, "KeyType": "HASH"}],
|
||||||
|
AttributeDefinitions=[{"AttributeName": hkey, "AttributeType": "S"}],
|
||||||
|
ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5},
|
||||||
|
)
|
||||||
|
update_expression = {
|
||||||
|
"Key": {hkey: "some_identification_string"},
|
||||||
|
"UpdateExpression": "set #AA.#AB = :aa",
|
||||||
|
"ExpressionAttributeValues": {":aa": "abc"},
|
||||||
|
"ExpressionAttributeNames": {"#AA": "some_dict", "#AB": "key1"},
|
||||||
|
"ConditionExpression": "attribute_not_exists(#AA.#AB)",
|
||||||
|
}
|
||||||
|
table = boto3.resource("dynamodb", region_name="us-west-2").Table(name)
|
||||||
|
with pytest.raises(ClientError) as err:
|
||||||
|
table.update_item(**update_expression)
|
||||||
|
err.value.response["Error"]["Code"].should.equal("ValidationException")
|
||||||
|
|
||||||
|
conn.scan(TableName=name)["Items"].should.have.length_of(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user