简体   繁体   中英

boto3 dynamodb PutItem with reserved word

i want to store some data to dynamodb table which has this primary key

partition key: invocationId
sort key: index

at the moment of using boto3 to PutItem the following error show up:

An error occurred (ValidationException) when calling the PutItem operation: Invalid ConditionExpression: Attribute name is a reserved keyword; reserved keyword: index

and indeed, index is part of reserved words list:( https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html

i tried the following code using ExpressionAttributeNames :

self._table.put_item(
    Item={
        '#I': entity.index,
        'invocationId': entity.invocationId,
        ...
    },
    ExpressionAttributeNames={
        '#I': 'index'
    },
)

but it raises:

An error occurred (ValidationException) when calling the PutItem operation: ExpressionAttributeNames can only be specified when using expressions

it's worth to mention that .net client works ok for the same use case, because i have put some records with index as sort key in that same table, but now it is required to use this table from python and boto3.

this is how it works in .net

AmazonDynamoDBClient DynamoClient = new AmazonDynamoDBClient();
var _table = Table.LoadTable(DynamoClient, "my-table-name");
var d = new Document()
            {
                ["invocationId"] = "...",
                ["index"] = "...",
            };
d.Add("newParam", "value");
d.Add(...);
_table.UpdateItemAsync(d).GetAwaiter().GetResult();

after this snippet execution, index column is populated correctly, so after all. it is possible.

You used the right solution - ExpressionAttributeNames - but in the wrong way.

When you define the "Item" to insert, you need to still use the full attribute name "index" - that's fine:

 Item={
        'index': entity.index,
        'invocationId': entity.invocationId,
        ...
    },

The word "index" in the item's definition was never the problem - the problem was (as the error message told you) that you used this word in an ConditionExpression . So you need to use this #I inside your ConditionExpression , and also pass ExpressionAttributeNames exactly like you did.

If you don't have a ConditionExpression (or some other expression) in your request, you don't need the #I , and not allowed to pass the unused ExpressionAttributeNames .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM