DynamoDB: Improve support for Update-statements in batch_execute-statement() (#7297)
This commit is contained in:
parent
3e775cad57
commit
62647ab1a3
@ -855,27 +855,31 @@ class DynamoDBBackend(BaseBackend):
|
|||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
response["TableName"] = table_name
|
response["TableName"] = table_name
|
||||||
table = self.tables[table_name]
|
if metadata.is_select_query():
|
||||||
for required_attr in table.table_key_attrs:
|
table = self.tables[table_name]
|
||||||
if required_attr not in filter_keys:
|
for required_attr in table.table_key_attrs:
|
||||||
response["Error"] = {
|
if required_attr not in filter_keys:
|
||||||
"Code": "ValidationError",
|
response["Error"] = {
|
||||||
"Message": "Select statements within BatchExecuteStatement must specify the primary key in the where clause.",
|
"Code": "ValidationError",
|
||||||
}
|
"Message": "Select statements within BatchExecuteStatement must specify the primary key in the where clause.",
|
||||||
|
}
|
||||||
responses.append(response)
|
responses.append(response)
|
||||||
|
|
||||||
# Execution
|
# Execution
|
||||||
for idx, stmt in enumerate(statements):
|
for idx, stmt in enumerate(statements):
|
||||||
if "Error" in responses[idx]:
|
if "Error" in responses[idx]:
|
||||||
continue
|
continue
|
||||||
items = self.execute_statement(
|
try:
|
||||||
statement=stmt["Statement"], parameters=stmt.get("Parameters", [])
|
items = self.execute_statement(
|
||||||
)
|
statement=stmt["Statement"], parameters=stmt.get("Parameters", [])
|
||||||
# Statements should always contain a HashKey and SortKey
|
)
|
||||||
# An item with those keys may not exist
|
# Statements should always contain a HashKey and SortKey
|
||||||
if items:
|
# An item with those keys may not exist
|
||||||
# But if it does, it will always only contain one item at most
|
if items:
|
||||||
responses[idx]["Item"] = items[0]
|
# 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
|
return responses
|
||||||
|
|
||||||
|
|
||||||
|
18
setup.cfg
18
setup.cfg
@ -54,7 +54,7 @@ all =
|
|||||||
openapi-spec-validator>=0.5.0
|
openapi-spec-validator>=0.5.0
|
||||||
pyparsing>=3.0.7
|
pyparsing>=3.0.7
|
||||||
jsondiff>=1.1.2
|
jsondiff>=1.1.2
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
aws-xray-sdk!=0.96,>=0.93
|
aws-xray-sdk!=0.96,>=0.93
|
||||||
setuptools
|
setuptools
|
||||||
multipart
|
multipart
|
||||||
@ -69,7 +69,7 @@ proxy =
|
|||||||
openapi-spec-validator>=0.5.0
|
openapi-spec-validator>=0.5.0
|
||||||
pyparsing>=3.0.7
|
pyparsing>=3.0.7
|
||||||
jsondiff>=1.1.2
|
jsondiff>=1.1.2
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
aws-xray-sdk!=0.96,>=0.93
|
aws-xray-sdk!=0.96,>=0.93
|
||||||
setuptools
|
setuptools
|
||||||
multipart
|
multipart
|
||||||
@ -84,7 +84,7 @@ server =
|
|||||||
openapi-spec-validator>=0.5.0
|
openapi-spec-validator>=0.5.0
|
||||||
pyparsing>=3.0.7
|
pyparsing>=3.0.7
|
||||||
jsondiff>=1.1.2
|
jsondiff>=1.1.2
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
aws-xray-sdk!=0.96,>=0.93
|
aws-xray-sdk!=0.96,>=0.93
|
||||||
setuptools
|
setuptools
|
||||||
flask!=2.2.0,!=2.2.1
|
flask!=2.2.0,!=2.2.1
|
||||||
@ -122,7 +122,7 @@ cloudformation =
|
|||||||
openapi-spec-validator>=0.5.0
|
openapi-spec-validator>=0.5.0
|
||||||
pyparsing>=3.0.7
|
pyparsing>=3.0.7
|
||||||
jsondiff>=1.1.2
|
jsondiff>=1.1.2
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
aws-xray-sdk!=0.96,>=0.93
|
aws-xray-sdk!=0.96,>=0.93
|
||||||
setuptools
|
setuptools
|
||||||
cloudfront =
|
cloudfront =
|
||||||
@ -145,10 +145,10 @@ dms =
|
|||||||
ds =
|
ds =
|
||||||
dynamodb =
|
dynamodb =
|
||||||
docker>=3.0.0
|
docker>=3.0.0
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
dynamodbstreams =
|
dynamodbstreams =
|
||||||
docker>=3.0.0
|
docker>=3.0.0
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
ebs =
|
ebs =
|
||||||
ec2 = sshpubkeys>=3.1.0
|
ec2 = sshpubkeys>=3.1.0
|
||||||
ec2instanceconnect =
|
ec2instanceconnect =
|
||||||
@ -213,15 +213,15 @@ resourcegroupstaggingapi =
|
|||||||
openapi-spec-validator>=0.5.0
|
openapi-spec-validator>=0.5.0
|
||||||
pyparsing>=3.0.7
|
pyparsing>=3.0.7
|
||||||
jsondiff>=1.1.2
|
jsondiff>=1.1.2
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
route53 =
|
route53 =
|
||||||
route53resolver =
|
route53resolver =
|
||||||
s3 =
|
s3 =
|
||||||
PyYAML>=5.1
|
PyYAML>=5.1
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
s3crc32c =
|
s3crc32c =
|
||||||
PyYAML>=5.1
|
PyYAML>=5.1
|
||||||
py-partiql-parser==0.5.0
|
py-partiql-parser==0.5.1
|
||||||
crc32c
|
crc32c
|
||||||
s3control =
|
s3control =
|
||||||
sagemaker =
|
sagemaker =
|
||||||
|
@ -334,6 +334,75 @@ def test_update_data(table_name=None):
|
|||||||
assert item2 in items
|
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
|
@pytest.mark.aws_verified
|
||||||
@dynamodb_aws_verified()
|
@dynamodb_aws_verified()
|
||||||
def test_delete_data(table_name=None):
|
def test_delete_data(table_name=None):
|
||||||
|
Loading…
Reference in New Issue
Block a user