Improve DDB transaction validation (#5521)
This commit is contained in:
parent
8486646f2d
commit
696b809b5a
@ -323,3 +323,12 @@ class InvalidConversion(JsonRESTError):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
er = "SerializationException"
|
er = "SerializationException"
|
||||||
super().__init__(er, "NUMBER_VALUE cannot be converted to String")
|
super().__init__(er, "NUMBER_VALUE cannot be converted to String")
|
||||||
|
|
||||||
|
|
||||||
|
class TransactWriteSingleOpException(MockValidationException):
|
||||||
|
there_can_be_only_one = (
|
||||||
|
"TransactItems can only contain one of Check, Put, Update or Delete"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(self.there_can_be_only_one)
|
||||||
|
@ -32,6 +32,7 @@ from moto.dynamodb.exceptions import (
|
|||||||
StreamAlreadyEnabledException,
|
StreamAlreadyEnabledException,
|
||||||
MockValidationException,
|
MockValidationException,
|
||||||
InvalidConversion,
|
InvalidConversion,
|
||||||
|
TransactWriteSingleOpException,
|
||||||
)
|
)
|
||||||
from moto.dynamodb.models.utilities import bytesize
|
from moto.dynamodb.models.utilities import bytesize
|
||||||
from moto.dynamodb.models.dynamo_type import DynamoType
|
from moto.dynamodb.models.dynamo_type import DynamoType
|
||||||
@ -1656,6 +1657,11 @@ class DynamoDBBackend(BaseBackend):
|
|||||||
|
|
||||||
errors = [] # [(Code, Message, Item), ..]
|
errors = [] # [(Code, Message, Item), ..]
|
||||||
for item in transact_items:
|
for item in transact_items:
|
||||||
|
# check transact writes are not performing multiple operations
|
||||||
|
# in the same item
|
||||||
|
if len(list(item.keys())) > 1:
|
||||||
|
raise TransactWriteSingleOpException
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if "ConditionCheck" in item:
|
if "ConditionCheck" in item:
|
||||||
item = item["ConditionCheck"]
|
item = item["ConditionCheck"]
|
||||||
@ -1682,6 +1688,7 @@ class DynamoDBBackend(BaseBackend):
|
|||||||
item = item["Put"]
|
item = item["Put"]
|
||||||
attrs = item["Item"]
|
attrs = item["Item"]
|
||||||
table_name = item["TableName"]
|
table_name = item["TableName"]
|
||||||
|
check_unicity(table_name, item)
|
||||||
condition_expression = item.get("ConditionExpression", None)
|
condition_expression = item.get("ConditionExpression", None)
|
||||||
expression_attribute_names = item.get(
|
expression_attribute_names = item.get(
|
||||||
"ExpressionAttributeNames", None
|
"ExpressionAttributeNames", None
|
||||||
|
@ -761,3 +761,42 @@ def test_query_begins_with_without_brackets():
|
|||||||
'Invalid KeyConditionExpression: Syntax error; token: "sk"'
|
'Invalid KeyConditionExpression: Syntax error; token: "sk"'
|
||||||
)
|
)
|
||||||
err["Code"].should.equal("ValidationException")
|
err["Code"].should.equal("ValidationException")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_dynamodb
|
||||||
|
def test_transact_write_items_multiple_operations_fail():
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
table_schema = {
|
||||||
|
"KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
|
||||||
|
"AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"}],
|
||||||
|
}
|
||||||
|
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
|
||||||
|
table_name = "test-table"
|
||||||
|
dynamodb.create_table(
|
||||||
|
TableName=table_name, BillingMode="PAY_PER_REQUEST", **table_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
# Execute
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
dynamodb.transact_write_items(
|
||||||
|
TransactItems=[
|
||||||
|
{
|
||||||
|
"Put": {
|
||||||
|
"Item": {"id": {"S": "test"}},
|
||||||
|
"TableName": table_name,
|
||||||
|
},
|
||||||
|
"Delete": {
|
||||||
|
"Key": {"id": {"S": "test"}},
|
||||||
|
"TableName": table_name,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
# Verify
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
assert err["Code"] == "ValidationException"
|
||||||
|
assert (
|
||||||
|
err["Message"]
|
||||||
|
== "TransactItems can only contain one of Check, Put, Update or Delete"
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user