使用KeyConditionExpression进行boto3查询

9

我不太明白为什么下面这个针对DynamoDB表的查询无法工作:

dict_table.query(KeyConditionExpression='norm = :cihan', ExpressionAttributeValues={':cihan': {'S': 'cihan'}})

并且抛出了以下错误:

ClientError: 调用查询操作时发生错误(ValidationException):一个或多个参数值无效:条件参数类型与模式类型不匹配

而以下内容是有效的:

dict_table.query(KeyConditionExpression=Key('norm').eq('cihan'))

norm是一个字符串类型的字段。我正在使用版本为1.4.0的boto3,并且遵循文档

In [43]: boto3.__version__
Out[43]: '1.4.0'

有人能看出第一个查询中的错误吗?

附加问题:为什么需要所有的令牌并且一直需要替换它们?我为什么不能只说dict_table.query(KeyConditionExpression='norm = cihan')

3个回答

7
请按照以下提到的方式更改ExpressionAttributeValues。
ExpressionAttributeValues={':cihan': 'cihan'}

2
谢谢,那个方法可行!但是为什么Boto3文档给出了以下示例?{ ":avail":{"S":"Available"}, ":back":{"S":"Backordered"}, ":disc":{"S":"Discontinued"} } 请参见http://boto3.readthedocs.io/en/latest/reference/services/dynamodb.html#DynamoDB.Client.query - tayfun
2
我同意,文档有误导性。它们让人觉得你为ExpressionAttributeValues提供的字典的值本身应该是带有'S'、'B'和'N'等键的字典,而我认为它只是试图表明这些是可能的值类型。 - nedned
再想一想,这似乎是不正确的。可能是来自以前版本的boto3 API。 - nedned

2

在当前版本的boto3(1.9.128)中,问题中提到的查询正常工作,现在除此之外没有其他内容可用,下面提到的查询对我有效:

dynamo_client.query( KeyConditionExpression='campaign_id = :201906', ExpressionAttributeValues={':201906': {'S': '201906'}} )

将"Original Answer"翻译成"最初的回答"

2

奖励问题...

为了回答您的奖励问题,所有令牌都是 Dynamo 使用的一种抽象层,以确保在与其通信时进行的 HTTP 请求的类型一致性。使用标准的 http/json,对于像“2”和2这样的情况存在歧义。因此,dynamo 强制客户端将值包装在特定定义其类型的对象中。

回到原始问题...

话虽如此...... boto3 API 不将其抽象化对您来说有点荒谬。尽管我可以理解它有点超出了 boto3 工具的范围。但是有希望,有一个名为 dynamof 的库。使用它,您的查询将如下所示:

from boto3 import client
from dynamof import db as make_db
from dynamof import query

client = client('dynamodb', endpoint_url='http://localstack:4569')
db = make_db(client)

results = db(query(
    table_name='dict_table',
    conditions=attr('norm').equals('cihan')
))

你可以使用相同的简单 API 进行 Dynamo 请求和其他常用操作,例如创建表、添加项目、更新、删除和扫描。更多操作和功能正在开发中。
免责声明:我编写了 dynamof。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接