如何使用boto3有条件地将项目插入到dynamodb表中

时间:2016-05-05 14:46:13

标签: python amazon-dynamodb boto3

如果我有一个带有userId的散列键和一个rangeId的范围键的表,那么只有在使用boto3的dynamodb绑定不存在的情况下,如何将该项放入该表?

对put_item的正常调用如下所示

table.put_item(Item={'userId': 1, 'productId': 2})

我使用ConditionExpression的调用如下所示:

table.put_item(
    Item={'userId': 1, 'productId': 2}, 
    ConditionExpression='userId <> :uid AND productId <> :pid', 
    ExpressionAttributeValues={':uid': 1, ':pid': 3}
)

但每次都会引发ConditionalCheckFailedException。项目是否存在具有相同productId的项目。

3 个答案:

答案 0 :(得分:46)

遗憾的是,这方面的文件并不是很清楚。我需要完成类似的事情,这对我有用,使用boto3:

try:
    table.put_item(
        Item={
            'foo':1,
            'bar':2,
        },
        ConditionExpression='attribute_not_exists(foo) AND attribute_not_exists(bar)'
    )
except botocore.exceptions.ClientError as e:
    # Ignore the ConditionalCheckFailedException, bubble up
    # other exceptions.
    if e.response['Error']['Code'] != 'ConditionalCheckFailedException':
        raise

与其他答案类似,关键在于attribute_not_exists函数,但最初我不清楚如何使其工作。经过一些实验,我能够顺利完成上述工作。

答案 1 :(得分:2)

我认为您将使用client.put_item而不是table.put_item获得更好的文档

来自boto3 documentation

  

要防止新项替换现有项,请使用包含attribute_not_exists函数的条件表达式,该函数的名称将用作表的分区键。由于每条记录都必须包含该属性,因此只有在没有匹配项的情况下,attribute_not_exists函数才会成功。

ConditionExpression:

  

ConditionExpression(string) - 必须满足的条件   命令条件PutItem操作成功。

     

表达式可以包含以下任何内容:

     

功能:attribute_exists | attribute_not_exists | attribute_type |   包含| starts_with | size这些函数名称区分大小写。

我在item.save()

上使用dynamodb2 overwrite parameter

答案 2 :(得分:0)

仅分区键或哈希键就足够了,不需要排序键(或范围键)。

try:
    table.put_item(
        Item={
            'foo':1,
            'bar':2,
        },
        ConditionExpression='attribute_not_exists(foo)'
    )
except botocore.exceptions.ClientError as e:
    # Ignore the ConditionalCheckFailedException, bubble up
    # other exceptions.
    if e.response['Error']['Code'] != 'ConditionalCheckFailedException':
        raise