如果我有一个带有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的项目。
答案 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()
答案 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