使用Boto3 DynamoDB条件表达式调用put_item时遇类型错误
问题原因
你用的是boto3低级客户端(client),但Attr()这类条件构造器是给**高级资源(resource)**设计的。低级客户端的ConditionExpression只接受字符串类型,而Attr()返回的是Or/And对象,类型不匹配才会报错。
解决方案
方案1:改用boto3资源(resource)接口
资源接口支持直接用Attr()构造的条件对象,代码修改如下:
import boto3 from boto3.dynamodb.conditions import Attr # 替换client为resource dynamodb = boto3.resource("dynamodb") table = dynamodb.Table("foo") example = { "id": "12345", # resource接口不用指定类型(如S),会自动推断 "name": "foo" } table.put_item( Item=example, ReturnValues="NONE", ConditionExpression=(Attr("name").not_exists() | Attr("name").eq(example.get("name"))) )
注意:resource接口的Item不需要像client那样写{"S": "foo"}这种格式,直接传原生Python类型就行,boto3会自动转成DynamoDB的类型。
方案2:继续用client接口,手动写条件表达式字符串
如果不想切换到resource,就把条件写成字符串,再通过ExpressionAttributeValues传变量值:
import boto3 client = boto3.client("dynamodb") example = { "id": {"S": "12345"}, "name": {"S": "foo"} } client.put_item( TableName="foo", Item=example, ReturnValues="NONE", ConditionExpression="attribute_not_exists(name) OR name = :name_val", ExpressionAttributeValues={":name_val": example.get("name")} )
这里用:name_val做占位符,再绑定实际值,完全符合client接口的参数要求。
内容的提问来源于stack exchange,提问作者Tony96
相关产品推荐
相关产品推荐

