AWS DynamoDB ScanInput中ExpressionAttributeValue不生效及类型兼容问题
我编写了一条DynamoDB的Scan查询,用于仅获取启用状态的数据,代码如下:
const FilterExpression = 'enabled = :enabled'; const ExpressionAttributeValues = { ':enabled': { 'BOOL': true } }; const scanParameters: ScanInput = { TableName, ExclusiveStartKey: cursor ?? undefined, Limit: Number(filter.limit) ?? undefined, FilterExpression, ExpressionAttributeValues, };
但该查询未返回任何结果。当我将ExpressionAttributeValues修改为:
const ExpressionAttributeValues = { ':enabled': true };
后能正常返回数据,却不符合ScanInput的类型要求,抛出如下错误:
"Type '{ ':enabled': boolean; }' is not assignable to type 'ExpressionAttributeValueMap'. Property '':enabled'' is incompatible with the index signature. "
我知道可通过自定义类型解决此问题,但为何符合ScanInput格式的数据执行扫描时无法生效?
核心原因是DynamoDB存储的enabled字段类型与查询时指定的类型不匹配,结合AWS SDK的处理逻辑,具体分为两点:
数据存储与查询的类型不匹配
你用{ 'BOOL': true }指定的是DynamoDB原生的结构化布尔类型,但如果表中enabled字段实际存储的是原生JSON布尔值(而非DynamoDB的BOOL类型结构),查询时就会因类型不匹配找不到对应数据。而直接传入true时,AWS SDK会自动将其转换为与存储类型匹配的格式,因此能正常返回结果。AWS SDK版本的处理差异
不同版本的AWS SDK对表达式属性值的处理逻辑不同:- 旧版SDK(如v2)允许直接传入原生类型(如
true),SDK会自动封装为DynamoDB的类型结构; - 新版SDK(如v3)的类型定义更严格,要求传入符合
ExpressionAttributeValueMap的结构,但如果数据是通过SDK自动转换原生类型写入的,手动编写{ BOOL: true }反而会导致类型不匹配。
- 旧版SDK(如v2)允许直接传入原生类型(如
简单来说:你写入数据时用的是原生布尔值,查询时却用了DynamoDB的结构化布尔类型,两者不匹配所以查不到数据;直接传原生布尔值时,SDK做了正确的类型转换,但类型定义未同步兼容,因此出现类型错误。
内容的提问来源于stack exchange,提问作者Ravi Sigdel

