如何在DynamoDB中正确查询布尔值并解决类型不匹配报错
这个报错和你代码里写的Python布尔值语法没关系,核心是DynamoDB的硬性规则:不管是主表主键,还是全局二级索引(GSI)、本地二级索引(LSI)的键字段,只支持字符串(S)、数字(N)、二进制(B)三种类型,布尔类型(BOOL)根本不能作为索引键使用。
你能成功创建complete_compliance_status-index这个索引,说明建索引时这个分区键声明的类型绝对不是布尔,要么是数字要么是字符串。你觉得字段里存的都是布尔值,实际上只有非键字段可以随便存布尔,能被索引收录的条目,必须满足索引键字段的类型和建索引时声明的类型完全一致——那些存了布尔值的条目根本没进这个GSI。你现在传布尔值False去匹配声明为数字/字符串类型的索引键,自然会触发类型不匹配的校验错误。
方案1:统一字段类型适配索引(生产环境推荐)
不要用布尔值存索引键内容,把complete_compliance_status字段的取值统一改成和建索引时声明的键类型一致:
- 如果建索引时键类型选的是数字(N):用
0代表False,1代表True,查询代码改成:
from boto3.dynamodb.conditions import Key response = cls.table_advisor_settings.query( IndexName = "complete_compliance_status-index", KeyConditionExpression=Key("complete_compliance_status").eq(0) )
- 如果建索引时键类型选的是字符串(S):用
"false"代表False,"true"代表True,查询时传对应字符串即可。
注意改完取值规则后要做一次全表数据回填,把历史存的布尔值全部替换成对应数字/字符串,否则老数据不会被索引同步,查询会漏结果。
方案2:全表扫描过滤(仅适合小体量测试表)
如果表数据量很小,不想改现有数据结构,可以直接用Scan操作加过滤条件匹配布尔值,不需要走索引。但要注意Scan会遍历全表所有数据,读容量消耗极高,数据量超过1万条就不建议用:
from boto3.dynamodb.conditions import Attr response = cls.table_advisor_settings.scan( FilterExpression=Attr("complete_compliance_status").eq(False) )
后续建DynamoDB索引时记住,只要是做主键、索引键的字段,类型只能选字符串、数字、二进制三类,布尔、集合、列表、Map这些类型都不支持作为键,不用浪费时间尝试给布尔字段建索引,服务端本身就不支持。
内容的提问来源于stack exchange,提问作者user14819175

