简体   繁体   中英

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"

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.

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.

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