如果我有一个散列键为
userId
且范围键为 productId
的表,那么如何使用 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的商品。
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 函数,但我最初不清楚如何让它发挥作用。经过一些实验,我能够按照上面的方法进行操作。
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
来自 boto3
文档:
要防止新项目替换现有项目,请使用包含 attribute_not_exists 函数的条件表达式,并将属性名称用作表的分区键。由于每个记录都必须包含该属性,因此 attribute_not_exists 函数仅在不存在匹配项时才会成功。条件表达式:
ConditionExpression (string) -- 必须满足的条件 命令条件 PutItem 操作成功。我正在使用 dynamodb2表达式可以包含以下任意内容:
函数:attribute_exists |属性不存在 |属性类型 | 包含 |开始于 | size 这些函数名称区分大小写。
attribute_not_exists
函数的条件表达式,并将属性名称用作表的分区键。您可以使用
errorfactory 它将根据返回的代码创建一个错误类。
import boto3
res = boto3.resource('dynamodb')
table = res.Table('mytable')
try:
conditionalUpdateResponse = table.put_item(
Item={'userId': 1, 'productId': 2},
ConditionExpression='attribute_not_exists(userId)',
)
except res.meta.client.exceptions.ConditionalCheckFailedException as e:
print(e)
来源:https://github.com/boto/boto3/issues/2235#issuecomment-574929483
AWS Boto3 文档:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/put_item.html