Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDB update a counter (or insert a key)

I have a function that is producing (some_key, some_value) pairs, that I want to put in my DynamoDB. If the item with key some_key is already present, I want to add some_value to the value attributes. Otherwise I want to create such item. Following the example in the docs it seems that the function if_not_exists should do what I want. I am having troubles with the syntax, because my code returns an error:

>>>> table.update_item(
        Key={
            'key': my_key
        },
        UpdateExpression="set my_value = if_not_exist(my_value + :inc, :inc)",

        ExpressionAttributeValues={
            ':inc': my_increment,
        },
        ReturnValues="UPDATED_NEW"
    )

ClientError: An error occurred (ValidationException) when calling the UpdateItem operation: 
Invalid UpdateExpression: Syntax error; token: "+", near: "coocc + :val"
like image 355
meto Avatar asked Feb 02 '16 21:02

meto


People also ask

What is the difference between put and update in DynamoDB?

Main Difference Between DynamoDB UpdateItem & PutItemThe putItem function is used to replace an existing item or to create a new item. In contrast, the updateItem function is used to add, edit or delete attributes from an existing item.

Can you update a record in DynamoDB?

To update an existing item in an Amazon DynamoDB table, you use the UpdateItem operation. You must provide the key of the item that you want to update. You must also provide an update expression, indicating the attributes that you want to modify and the values that you want to assign to them.

Can you update sort key value DynamoDB?

Can we update the sort key in DynamoDB? No, you can not update the sort key after the table is provisioned. However, you can create a new table and put the existing data in the newly created table, and delete the old table.

Does DynamoDB PutItem overwrite?

By default, the DynamoDB write operations ( PutItem , UpdateItem , DeleteItem ) are unconditional: Each operation overwrites an existing item that has the specified primary key.


2 Answers

You can do it like this:

table.update_item(
    Key={
        'key': my_key
    },
    UpdateExpression="SET my_value = if_not_exists(my_value, :start) + :inc",

    ExpressionAttributeValues={
        ':inc': my_increment,
        ':start': 0,
    },
    ReturnValues="UPDATED_NEW"
)

The update_item will whether create the new item or update existing.

The UpdateExpression will check if my_value already exists and use existing my_value + :inc.

If my_value does not exist then it will use :start as initial value.

like image 193
Boris Serebrov Avatar answered Oct 06 '22 02:10

Boris Serebrov


For this type of operations you could simply use ADD function. From the docs:

ADD - Adds the specified value to the item, if the attribute does not already exist. If the attribute does exist, then the behavior of ADD depends on the data type of the attribute

So by using boto3.client() you can do the following:

client.update_item(
    TableName='MyTable',
    Key={'myhash': {'S': 'myvalue'}},
    UpdateExpression="ADD #counter :increment",
    ExpressionAttributeNames={'#counter': 'counter'},
    ExpressionAttributeValues={':increment': {'N': '1'}}
) 

This will create counter field if it doesn't exist and it will increment it if it does exist.

like image 36
Vor Avatar answered Oct 06 '22 03:10

Vor