DynamoDB更新计数器(或插入密钥)

时间:2016-02-02 21:27:30

标签: python amazon-web-services amazon-dynamodb

我有一个生成(some_key, some_value)对的函数,我希望将它放在我的DynamoDB中。如果包含密钥some_key的项目已存在,我想将some_value添加到value属性中。否则我想创建这样的项目。按照the docs中的示例,似乎函数if_not_exists应该按照我的意愿行事。我遇到了语法问题,因为我的代码返回错误:

>>>> 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"

2 个答案:

答案 0 :(得分:11)

对于此类操作,您只需使用ADD功能即可。 来自docs

  

ADD - 如果属性没有,则将指定的值添加到项目中   已经存在。如果该属性确实存在,那么ADD的行为   取决于属性的数据类型

因此,使用boto3.client()可以执行以下操作:

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

如果该字段不存在,则会创建counter字段,如果该字段存在,则会增加该字段。

答案 1 :(得分:8)

你可以这样做:

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"
)

update_item将创建新项目还是更新现有项目。

UpdateExpression将检查my_value是否已存在并使用现有的my_value + :inc

如果my_value不存在,那么它将使用:start作为初始值。