DynamoDB - error when sending an integer as string (#5108)
This commit is contained in:
parent
4a5c72d5ed
commit
ff767d0743
@ -310,3 +310,9 @@ class StreamAlreadyEnabledException(JsonRESTError):
|
||||
def __init__(self):
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceInUseException"
|
||||
super().__init__(er, "Cannot enable stream")
|
||||
|
||||
|
||||
class InvalidConversion(JsonRESTError):
|
||||
def __init__(self):
|
||||
er = "SerializationException"
|
||||
super().__init__(er, "NUMBER_VALUE cannot be converted to String")
|
||||
|
@ -33,6 +33,7 @@ from moto.dynamodb.exceptions import (
|
||||
ResourceInUseException,
|
||||
StreamAlreadyEnabledException,
|
||||
MockValidationException,
|
||||
InvalidConversion,
|
||||
)
|
||||
from moto.dynamodb.models.utilities import bytesize
|
||||
from moto.dynamodb.models.dynamo_type import DynamoType
|
||||
@ -646,6 +647,13 @@ class Table(CloudFormationModel):
|
||||
if DynamoType(range_value).size() > RANGE_KEY_MAX_LENGTH:
|
||||
raise RangeKeyTooLong
|
||||
|
||||
def _validate_item_types(self, item_attrs):
|
||||
for key, value in item_attrs.items():
|
||||
if type(value) == dict:
|
||||
self._validate_item_types(value)
|
||||
elif type(value) == int and key == "N":
|
||||
raise InvalidConversion
|
||||
|
||||
def put_item(
|
||||
self,
|
||||
item_attrs,
|
||||
@ -688,6 +696,8 @@ class Table(CloudFormationModel):
|
||||
|
||||
self._validate_key_sizes(item_attrs)
|
||||
|
||||
self._validate_item_types(item_attrs)
|
||||
|
||||
if expected is None:
|
||||
expected = {}
|
||||
lookup_range_value = range_value
|
||||
|
@ -1,9 +1,11 @@
|
||||
import boto3
|
||||
import botocore
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from boto3.dynamodb.conditions import Key
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_dynamodb
|
||||
from unittest import SkipTest
|
||||
from moto import mock_dynamodb, settings
|
||||
|
||||
table_schema = {
|
||||
"KeySchema": [{"AttributeName": "partitionKey", "KeyType": "HASH"}],
|
||||
@ -547,3 +549,33 @@ def test_update_item_non_existent_table():
|
||||
err = exc.value.response["Error"]
|
||||
assert err["Code"].should.equal("ResourceNotFoundException")
|
||||
assert err["Message"].should.equal("Requested resource not found")
|
||||
|
||||
|
||||
@mock_dynamodb
|
||||
def test_put_item_wrong_datatype():
|
||||
if settings.TEST_SERVER_MODE:
|
||||
raise SkipTest("Unable to mock a session with Config in ServerMode")
|
||||
session = botocore.session.Session()
|
||||
config = botocore.client.Config(parameter_validation=False)
|
||||
client = session.create_client("dynamodb", region_name="us-east-1", config=config)
|
||||
client.create_table(
|
||||
TableName="test2",
|
||||
KeySchema=[{"AttributeName": "mykey", "KeyType": "HASH"}],
|
||||
AttributeDefinitions=[{"AttributeName": "mykey", "AttributeType": "N"}],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)
|
||||
with pytest.raises(ClientError) as exc:
|
||||
client.put_item(TableName="test2", Item={"mykey": {"N": 123}})
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("SerializationException")
|
||||
err["Message"].should.equal("NUMBER_VALUE cannot be converted to String")
|
||||
|
||||
# Same thing - but with a non-key, and nested
|
||||
with pytest.raises(ClientError) as exc:
|
||||
client.put_item(
|
||||
TableName="test2",
|
||||
Item={"mykey": {"N": "123"}, "nested": {"M": {"sth": {"N": 5}}}},
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("SerializationException")
|
||||
err["Message"].should.equal("NUMBER_VALUE cannot be converted to String")
|
||||
|
Loading…
x
Reference in New Issue
Block a user