DynamoDB: Improve support for Update-statements in batch_execute-statement() (#7297)
This commit is contained in:
		
							parent
							
								
									3e775cad57
								
							
						
					
					
						commit
						62647ab1a3
					
				| @ -855,6 +855,7 @@ class DynamoDBBackend(BaseBackend): | ||||
|                 } | ||||
|             else: | ||||
|                 response["TableName"] = table_name | ||||
|                 if metadata.is_select_query(): | ||||
|                     table = self.tables[table_name] | ||||
|                     for required_attr in table.table_key_attrs: | ||||
|                         if required_attr not in filter_keys: | ||||
| @ -868,6 +869,7 @@ class DynamoDBBackend(BaseBackend): | ||||
|         for idx, stmt in enumerate(statements): | ||||
|             if "Error" in responses[idx]: | ||||
|                 continue | ||||
|             try: | ||||
|                 items = self.execute_statement( | ||||
|                     statement=stmt["Statement"], parameters=stmt.get("Parameters", []) | ||||
|                 ) | ||||
| @ -876,6 +878,8 @@ class DynamoDBBackend(BaseBackend): | ||||
|                 if items: | ||||
|                     # But if it does, it will always only contain one item at most | ||||
|                     responses[idx]["Item"] = items[0] | ||||
|             except Exception as e: | ||||
|                 responses[idx] = {"Error": {"Code": e.name, "Message": e.message}}  # type: ignore | ||||
|         return responses | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										18
									
								
								setup.cfg
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								setup.cfg
									
									
									
									
									
								
							| @ -54,7 +54,7 @@ all = | ||||
|     openapi-spec-validator>=0.5.0 | ||||
|     pyparsing>=3.0.7 | ||||
|     jsondiff>=1.1.2 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
|     aws-xray-sdk!=0.96,>=0.93 | ||||
|     setuptools | ||||
|     multipart | ||||
| @ -69,7 +69,7 @@ proxy = | ||||
|     openapi-spec-validator>=0.5.0 | ||||
|     pyparsing>=3.0.7 | ||||
|     jsondiff>=1.1.2 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
|     aws-xray-sdk!=0.96,>=0.93 | ||||
|     setuptools | ||||
|     multipart | ||||
| @ -84,7 +84,7 @@ server = | ||||
|     openapi-spec-validator>=0.5.0 | ||||
|     pyparsing>=3.0.7 | ||||
|     jsondiff>=1.1.2 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
|     aws-xray-sdk!=0.96,>=0.93 | ||||
|     setuptools | ||||
|     flask!=2.2.0,!=2.2.1 | ||||
| @ -122,7 +122,7 @@ cloudformation = | ||||
|     openapi-spec-validator>=0.5.0 | ||||
|     pyparsing>=3.0.7 | ||||
|     jsondiff>=1.1.2 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
|     aws-xray-sdk!=0.96,>=0.93 | ||||
|     setuptools | ||||
| cloudfront = | ||||
| @ -145,10 +145,10 @@ dms = | ||||
| ds = | ||||
| dynamodb = | ||||
|     docker>=3.0.0 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
| dynamodbstreams = | ||||
|     docker>=3.0.0 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
| ebs = | ||||
| ec2 = sshpubkeys>=3.1.0 | ||||
| ec2instanceconnect = | ||||
| @ -213,15 +213,15 @@ resourcegroupstaggingapi = | ||||
|     openapi-spec-validator>=0.5.0 | ||||
|     pyparsing>=3.0.7 | ||||
|     jsondiff>=1.1.2 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
| route53 = | ||||
| route53resolver = | ||||
| s3 = | ||||
|     PyYAML>=5.1 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
| s3crc32c = | ||||
|     PyYAML>=5.1 | ||||
|     py-partiql-parser==0.5.0 | ||||
|     py-partiql-parser==0.5.1 | ||||
|     crc32c | ||||
| s3control = | ||||
| sagemaker = | ||||
|  | ||||
| @ -334,6 +334,75 @@ def test_update_data(table_name=None): | ||||
|     assert item2 in items | ||||
| 
 | ||||
| 
 | ||||
| @mock_aws | ||||
| def test_batch_update__not_enough_parameters(): | ||||
|     ddb_cli = boto3.client("dynamodb", "us-east-1") | ||||
|     ddb_res = boto3.resource("dynamodb", "us-east-1") | ||||
|     ddb_res.create_table( | ||||
|         TableName="users", | ||||
|         KeySchema=[{"AttributeName": "username", "KeyType": "HASH"}], | ||||
|         AttributeDefinitions=[{"AttributeName": "username", "AttributeType": "S"}], | ||||
|         ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5}, | ||||
|     ) | ||||
| 
 | ||||
|     statements = [ | ||||
|         { | ||||
|             "Statement": 'UPDATE users SET "first_name" = ?, "last_name" = ? WHERE "username"= ?', | ||||
|             "Parameters": [{"S": "test5"}, {"S": "test6"}], | ||||
|         } | ||||
|     ] | ||||
|     resp = ddb_cli.batch_execute_statement(Statements=statements)["Responses"] | ||||
|     assert resp == [ | ||||
|         { | ||||
|             "Error": { | ||||
|                 "Code": "ValidationError", | ||||
|                 "Message": "Number of parameters in request and statement don't match.", | ||||
|             } | ||||
|         } | ||||
|     ] | ||||
| 
 | ||||
| 
 | ||||
| @mock_aws | ||||
| def test_batch_update(): | ||||
|     ddb_cli = boto3.client("dynamodb", "us-east-1") | ||||
|     ddb_res = boto3.resource("dynamodb", "us-east-1") | ||||
|     table = ddb_res.create_table( | ||||
|         TableName="users", | ||||
|         KeySchema=[{"AttributeName": "username", "KeyType": "HASH"}], | ||||
|         AttributeDefinitions=[{"AttributeName": "username", "AttributeType": "S"}], | ||||
|         ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5}, | ||||
|     ) | ||||
|     table.put_item( | ||||
|         Item={"username": "XXXX", "first_name": "test1", "last_name": "test2"} | ||||
|     ) | ||||
|     table.put_item( | ||||
|         Item={"username": "YYYY", "first_name": "test3", "last_name": "test4"} | ||||
|     ) | ||||
| 
 | ||||
|     statements = [ | ||||
|         { | ||||
|             "Statement": 'UPDATE users SET "first_name" = ?, "last_name" = ? WHERE "username"= ?', | ||||
|             "Parameters": [{"S": "test5"}, {"S": "test6"}, {"S": "XXXX"}], | ||||
|         }, | ||||
|         {"Statement": "DELETE FROM users WHERE username='YYYY'"}, | ||||
|         {"Statement": "INSERT INTO users value {'username': 'new'}"}, | ||||
|     ] | ||||
|     response = ddb_cli.batch_execute_statement(Statements=statements)["Responses"] | ||||
|     assert response == [ | ||||
|         {"TableName": "users"}, | ||||
|         {"TableName": "users"}, | ||||
|         {"TableName": "users"}, | ||||
|     ] | ||||
| 
 | ||||
|     users = ddb_res.Table("users").scan()["Items"] | ||||
|     assert len(users) == 2 | ||||
| 
 | ||||
|     # Changed | ||||
|     assert {"username": "XXXX", "first_name": "test5", "last_name": "test6"} in users | ||||
|     # New | ||||
|     assert {"username": "new"} in users | ||||
| 
 | ||||
| 
 | ||||
| @pytest.mark.aws_verified | ||||
| @dynamodb_aws_verified() | ||||
| def test_delete_data(table_name=None): | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user