Python boto3查询DynamoDB时间范围数据出现ValidationException如何解决?
问题根因
- 语法错误:
FilterExpression中between的参数:ts1、:ts2被额外加了单引号,导致被识别为普通字符串常量,没有和ExpressionAttributeValues中定义的变量绑定,因此DynamoDB判定这两个变量未被使用,抛出对应校验异常。 - 逻辑错误:
timestamp是表的排序键,范围条件完全可以放到KeyConditionExpression中执行,放在FilterExpression中会先查询全部分区键匹配的条目再做过滤,浪费读容量,查询性能也更差。
修正代码
如果使用boto3的resource接口(无需手动指定属性类型,框架会自动映射),正确写法如下:
import boto3 from boto3.dynamodb.conditions import Key dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('你的表名') response = table.query( # 分区键匹配+排序键范围条件都放在KeyConditionExpression中,直接命中索引 KeyConditionExpression=Key('deviceid').eq(':deviceid') & Key('timestamp').between(':ts1', ':ts2'), ExpressionAttributeValues={ ':deviceid': 'BSM_G101', ':ts1': "2021-09-12 10:56:26", ':ts2': "2021-09-12 10:57:00" } )
如果使用boto3的client接口,需要手动指定属性类型:
import boto3 client = boto3.client('dynamodb') response = client.query( TableName='你的表名', KeyConditionExpression='deviceid = :deviceid AND #ts BETWEEN :ts1 AND :ts2', ExpressionAttributeNames={ '#ts': 'timestamp' }, ExpressionAttributeValues={ ':deviceid': {'S': 'BSM_G101'}, ':ts1': {'S': "2021-09-12 10:56:26"}, ':ts2': {'S': "2021-09-12 10:57:00"} } )
注意事项
如果确实需要对非键属性做过滤,使用FilterExpression时切记变量占位符不要加额外引号,直接写入变量名即可,例:FilterExpression=Key('non_key_attr').gt(:threshold)
内容的提问来源于stack exchange,提问作者Pankaj Sant
相关产品推荐
相关产品推荐

