DynamoDB: Allow attribute name 'S' (#6185)

This commit is contained in:
Bert Blommers 2023-04-07 21:02:00 +00:00 committed by GitHub
parent dc460a3258
commit 1111e10b87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 3 deletions

View File

@ -484,10 +484,12 @@ class Table(CloudFormationModel):
if DynamoType(range_value).size() > RANGE_KEY_MAX_LENGTH:
raise RangeKeyTooLong
def _validate_item_types(self, item_attrs: Dict[str, Any]) -> None:
def _validate_item_types(
self, item_attrs: Dict[str, Any], attr: Optional[str] = None
) -> None:
for key, value in item_attrs.items():
if type(value) == dict:
self._validate_item_types(value)
self._validate_item_types(value, attr=key if attr is None else key)
elif type(value) == int and key == "N":
raise InvalidConversion
if key == "S":
@ -497,7 +499,7 @@ class Table(CloudFormationModel):
raise SerializationException(
"NUMBER_VALUE cannot be converted to String"
)
if type(value) == dict:
if attr and attr in self.table_key_attrs and type(value) == dict:
raise SerializationException(
"Start of structure or map found where not expected"
)

View File

@ -933,12 +933,21 @@ def test_put_item__string_as_integer_value():
err["Code"].should.equal("SerializationException")
err["Message"].should.equal("NUMBER_VALUE cannot be converted to String")
# A primary key cannot be of type S, but then point to a dictionary
with pytest.raises(ClientError) as exc:
client.put_item(TableName="without_sk", Item={"pk": {"S": {"S": "asdf"}}})
err = exc.value.response["Error"]
err["Code"].should.equal("SerializationException")
err["Message"].should.equal("Start of structure or map found where not expected")
# Note that a normal attribute name can be an 'S', which follows the same pattern
# Nested 'S'-s like this are allowed for non-key attributes
client.put_item(
TableName="without_sk", Item={"pk": {"S": "val"}, "S": {"S": "asdf"}}
)
item = client.get_item(TableName="without_sk", Key={"pk": {"S": "val"}})["Item"]
assert item == {"pk": {"S": "val"}, "S": {"S": "asdf"}}
@mock_dynamodb
def test_gsi_key_cannot_be_empty():