Skip to content

Commit

Permalink
DynamoDB: empty update expression now returns a ValidationException (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
felixscherz authored Aug 16, 2024
1 parent 856ded1 commit 3827cce
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
14 changes: 12 additions & 2 deletions moto/dynamodb/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,12 +889,22 @@ def update_item(self) -> str:
name = self.body["TableName"]
key = self.body["Key"]
return_values = self.body.get("ReturnValues", "NONE")
update_expression = self.body.get("UpdateExpression", "").strip()
update_expression = self.body.get("UpdateExpression", None)
attribute_updates = self.body.get("AttributeUpdates")
if update_expression and attribute_updates:
if update_expression is not None and attribute_updates:
raise MockValidationException(
"Can not use both expression and non-expression parameters in the same request: Non-expression parameters: {AttributeUpdates} Expression parameters: {UpdateExpression}"
)

if update_expression is not None:
update_expression = update_expression.strip()
if update_expression == "":
raise MockValidationException(
"Invalid UpdateExpression: The expression can not be empty;"
)
else:
update_expression = ""

return_values_on_condition_check_failure = self.body.get(
"ReturnValuesOnConditionCheckFailure"
)
Expand Down
25 changes: 25 additions & 0 deletions tests/test_dynamodb/test_dynamodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3864,6 +3864,31 @@ def test_error_when_providing_expression_and_nonexpression_params():
)


@mock_aws
def test_error_when_providing_empty_update_expression():
client = boto3.client("dynamodb", "eu-central-1")
table_name = "testtable"
client.create_table(
TableName=table_name,
KeySchema=[{"AttributeName": "pkey", "KeyType": "HASH"}],
AttributeDefinitions=[{"AttributeName": "pkey", "AttributeType": "S"}],
BillingMode="PAY_PER_REQUEST",
)

with pytest.raises(ClientError) as ex:
client.update_item(
TableName=table_name,
Key={"pkey": {"S": "testrecord"}},
UpdateExpression="",
ExpressionAttributeValues={":order": {"SS": ["item"]}},
)
err = ex.value.response["Error"]
assert err["Code"] == "ValidationException"
assert (
err["Message"] == "Invalid UpdateExpression: The expression can not be empty;"
)


@mock_aws
def test_attribute_item_delete():
name = "TestTable"
Expand Down
19 changes: 19 additions & 0 deletions tests/test_dynamodb/test_dynamodb_update_expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,22 @@ def test_update_item_with_empty_values(table_name=None):
err = exc.value.response["Error"]
assert err["Code"] == "ValidationException"
assert err["Message"] == "ExpressionAttributeValues must not be empty"


@pytest.mark.aws_verified
@dynamodb_aws_verified()
def test_update_item_with_empty_expression(table_name=None):
dynamodb = boto3.client("dynamodb", "us-east-1")

dynamodb.put_item(TableName=table_name, Item={"pk": {"S": "foo"}})
with pytest.raises(ClientError) as exc:
dynamodb.update_item(
TableName=table_name,
Key={"pk": {"S": "foo"}},
UpdateExpression="",
)
err = exc.value.response["Error"]
assert err["Code"] == "ValidationException"
assert (
err["Message"] == "Invalid UpdateExpression: The expression can not be empty;"
)

0 comments on commit 3827cce

Please sign in to comment.