DynamoDB: fix: Add support for ReturnValuesOnConditionCheckFailure=ALL_OLD (#5676)
				
					
				
			This commit is contained in:
		
							parent
							
								
									dfd45d80ab
								
							
						
					
					
						commit
						310ef4885a
					
				| @ -1701,6 +1701,17 @@ class DynamoDBBackend(BaseBackend): | |||||||
|                     expression_attribute_values = item.get( |                     expression_attribute_values = item.get( | ||||||
|                         "ExpressionAttributeValues", None |                         "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( |                     self.put_item( | ||||||
|                         table_name, |                         table_name, | ||||||
|                         attrs, |                         attrs, | ||||||
|  | |||||||
| @ -3896,6 +3896,60 @@ def test_transact_write_items_put_conditional_expressions(): | |||||||
|     items[0].should.equal({"id": {"S": "foo2"}}) |     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 | @mock_dynamodb | ||||||
| def test_transact_write_items_conditioncheck_passes(): | def test_transact_write_items_conditioncheck_passes(): | ||||||
|     table_schema = { |     table_schema = { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user