DynamoDB: fix: Add support for ReturnValuesOnConditionCheckFailure=ALL_OLD (#5676)

This commit is contained in:
jake-sigtech 2022-11-18 21:51:51 +00:00 committed by GitHub
parent dfd45d80ab
commit 310ef4885a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 0 deletions

View File

@ -1701,6 +1701,17 @@ class DynamoDBBackend(BaseBackend):
expression_attribute_values = item.get(
"ExpressionAttributeValues", None
)
return_values_on_condition_check_failure = item.get(
"ReturnValuesOnConditionCheckFailure", None
)
current = self.get_item(table_name, attrs)
if (
return_values_on_condition_check_failure == "ALL_OLD"
and current
):
item["Item"] = current.to_json()["Attributes"]
self.put_item(
table_name,
attrs,

View File

@ -3896,6 +3896,60 @@ def test_transact_write_items_put_conditional_expressions():
items[0].should.equal({"id": {"S": "foo2"}})
@mock_dynamodb
def test_transact_write_items_put_conditional_expressions_return_values_on_condition_check_failure_all_old():
table_schema = {
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"}],
}
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
dynamodb.create_table(
TableName="test-table", BillingMode="PAY_PER_REQUEST", **table_schema
)
dynamodb.put_item(TableName="test-table", Item={"id": {"S": "foo2"}})
# Put multiple items
with pytest.raises(ClientError) as ex:
dynamodb.transact_write_items(
TransactItems=[
{
"Put": {
"Item": {
"id": {"S": "foo{}".format(str(i))},
"foo": {"S": "bar"},
},
"TableName": "test-table",
"ConditionExpression": "#i <> :i",
"ExpressionAttributeNames": {"#i": "id"},
"ReturnValuesOnConditionCheckFailure": "ALL_OLD",
"ExpressionAttributeValues": {
":i": {
"S": "foo2"
} # This item already exist, so the ConditionExpression should fail
},
}
}
for i in range(0, 5)
]
)
# Assert the exception is correct
ex.value.response["Error"]["Code"].should.equal("TransactionCanceledException")
reasons = ex.value.response["CancellationReasons"]
reasons.should.have.length_of(5)
reasons.should.contain(
{
"Code": "ConditionalCheckFailed",
"Message": "The conditional request failed",
"Item": {"id": {"S": "foo2"}},
}
)
reasons.should.contain({"Code": "None"})
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Assert all are present
items = dynamodb.scan(TableName="test-table")["Items"]
items.should.have.length_of(1)
items[0].should.equal({"id": {"S": "foo2"}})
@mock_dynamodb
def test_transact_write_items_conditioncheck_passes():
table_schema = {