Search code examples
amazon-web-servicesamazon-dynamodbaws-cli

"Parameter validation failed: Invalid type for parameter" on update item in DynamoDB to a different type


I need to update values in DynamoDB, original value is a string, new value is a number. The error returned

Parameter validation failed: Invalid type for parameter ExpressionAttributeValues.:ttl.N, value: 1696989709, type: <class 'int'>, valid types: <class 'str'>

Command:

aws dynamodb update-item \
--table-name my-datastore \
--key '{"Id": {"N": "456"}}'  \
--update-expression "SET expire_at = :ttl" \
--condition-expression "attribute_type(expire_at, :date_str)" \
--expression-attribute-values '{":ttl": {"N": 1696989709}, ":date_str": {"S": "S"}}'

CLI version is

aws-cli/2.11.21 Python/3.11.4 Darwin/21.6.0 source/arm64 prompt/off

The column 'expire_at' is specified on DynamoDB as TTL

   TimeToLiveSpecification:
     AttributeName: expire_at
     Enabled: true

Is there a way to update a string value to a number value?

Update: When ttl is specified as

":ttl": {"N": "1696989709"}

it returns a different error:

An error occurred (ValidationException) when calling the UpdateItem operation: The provided key element does not match the schema

Table definition

aws dynamodb describe-table --table-name my-datastore;
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "created_at",
                "AttributeType": "S"
            },
            {
                "AttributeName": "profile_key",
                "AttributeType": "S"
            },
            {
                "AttributeName": "user_id",
                "AttributeType": "S"
            }
        ],
        "TableName": "my-datastore",
        "KeySchema": [
            {
                "AttributeName": "user_id",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "created_at",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2023-06-21T14:50:16.470000-04:00",
        "ProvisionedThroughput": {
            "LastDecreaseDateTime": "2023-06-21T15:02:10.890000-04:00",
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 5,
            "WriteCapacityUnits": 5
        },
        "TableSizeBytes": 1439,
        "ItemCount": 9,
        "TableArn": "arn:aws:dynamodb:us-east-1:{acct}:table/my-datastore",
        "TableId": "{table-id}",
        "GlobalSecondaryIndexes": [
            {
                "IndexName": "by_profile_key",
                "KeySchema": [
                    {
                        "AttributeName": "profile_key",
                        "KeyType": "HASH"
                    },
                    {
                        "AttributeName": "created_at",
                        "KeyType": "RANGE"
                    }
                ],
                "Projection": {
                    "ProjectionType": "ALL"
                },
                "IndexStatus": "ACTIVE",
                "ProvisionedThroughput": {
                    "NumberOfDecreasesToday": 0,
                    "ReadCapacityUnits": 5,
                    "WriteCapacityUnits": 5
                },
                "IndexSizeBytes": 1439,
                "ItemCount": 9,
                "IndexArn": "arn:aws:dynamodb:us-east-1:{account}:table/my-datastore/index/by_profile_key"
            }
        ],
        "SSEDescription": {
            "Status": "ENABLED",
            "SSEType": "KMS",
            "KMSMasterKeyArn": "arn:aws:kms:us-east-1:{account}:key/{key}"
        },
        "DeletionProtectionEnabled": false
    }
}

Solution

  • As Jason stated, change the TTL value in expressionAttributeValues:

    aws dynamodb update-item \
    --table-name my-datastore \
    --key '{"Id": {"N": "456"}}'  \
    --update-expression "SET expire_at = :ttl" \
    --condition-expression "attribute_type(expire_at, :date_str)" \
    --expression-attribute-values '{":ttl": {"N": "1696989709"}, ":date_str": {"S": "S"}}'
    

    As for the exception:

    An error occurred (ValidationException) when calling the UpdateItem operation: The provided key element does not match the schema

    You need to also show us the output of:

    aws dynamodb describe-table \
    --table-name my-datastore
    

    Works for me:

    Before

    aws dynamodb get-item \
    --table-name my-datastore \
    --key '{"Id":{"N":"456"}}' \
    --consistent-read
    
    {
        "Item": {
            "Id": {
                "N": "456"
            },
            "expire_at": {
                "S": "2384023948"
            }
        }
    }
    

    Update

    aws dynamodb update-item \
    --table-name my-datastore \
    --key '{"Id": {"N": "456"}}'  \
    --update-expression "SET expire_at = :ttl" \
    --condition-expression "attribute_type(expire_at, :date_str)" \
    --expression-attribute-values '{":ttl": {"N": "1696989709"}, ":date_str": {"S": "S"}}'
    

    After

    aws dynamodb get-item \
    --table-name my-datastore \
    --key '{"Id":{"N":"456"}}' \
    --consistent-read
    {
        "Item": {
            "Id": {
                "N": "456"
            },
            "expire_at": {
                "N": "1696989709"
            }
        }
    }
    

    Update

    Based on your update you're trying to update an item without specifying it's keys user_id and created_at, without specifying both those values you will not be able to update the item.

    Request

    aws dynamodb update-item \
    --table-name my-datastore \
    --key '{"user_id": {"S": "some-user-id"}, {"create_at": {"S": "some-created_at-value"}}'  \
    --update-expression "SET expire_at = :ttl" \
    --condition-expression "attribute_type(expire_at, :date_str)" \
    --expression-attribute-values '{":ttl": {"N": "1696989709"}, ":date_str": {"S": "S"}}'