Filter Expression can only contain non-primary key attributes
TL;DR — 你把一个主键属性(分区键或排序键——无论是表的还是你所查询的索引的)放进了 FilterExpression。DynamoDB 禁止这样做:键属性进 KeyConditionExpression,而过滤器只能引用非键属性。把键条件移到它该在的地方。
含义
ValidationException: Filter Expression can only contain non-primary key attributes:
Primary key attribute: <name>
# what the engine actually returns, reproduced against DynamoDB Local:
ValidationException: Filter Expression can only contain non-primary key attributes: Primary key attribute: pkFilterExpression 在项目被读取之后运行,用来丢弃你不想要的行;KeyConditionExpression 在之前运行,用来按键选择读取哪些项目。在过滤器中引用分区键/排序键混淆了这些角色,因此 DynamoDB 以一个 HTTP 400 ValidationException 拒绝它——属于客户端错误,在你重构之前不可重试。
为什么会发生
- 把键条件写成了过滤器——
FilterExpression: 'sk = :v',其中sk是排序键;它属于KeyConditionExpression。 - 对索引的键做过滤——当你
Query一个 GSI/LSI 时,那个索引自己的分区键/排序键对本次查询而言就是"主键属性",不能出现在过滤器中。 - 把一个 scan 过滤器复制粘贴到一个 query 上,而其中一个被过滤的属性恰好是键。
- 试图通过过滤器为排序键添加第二个条件(例如一个范围),而不是在键条件中表达它。
如何修复
- 把键条件移入
KeyConditionExpression:KeyConditionExpression: 'pk = :pk AND begins_with(sk, :prefix)', // FilterExpression: only NON-key attributes, e.g. 'status = :active' - 使用正确的索引。 如果你需要在一个非键属性上过滤/选择,就把它建模为某个 GSI 的分区键/排序键并按键查询那个索引。
- 让过滤器只用于非键属性——它会裁剪结果,但仍然会为扫描到的每个项目消耗读取容量,因此要依靠键/索引来做选择。
- 在查询 GSI? 记住它的键属性在过滤器里同样禁用——在键条件中对它们做条件。
在 DynoTable 中运行
DynoTable 的查询面板将关键条件和过滤器保留在单独的字段中 - 分区和排序键约束永远不会落在 FilterExpression 中。用⌘K打开一张表,设置关键条件,然后添加非关键过滤器;将生成的请求复制到你的 SDK 中。使用 Query Builder 原型 GSI 查询,其中索引键必须保留在 KeyConditionExpression 中。使用 ⌘P 切换配置文件;在“设置”→“配置文件”上Test Connection,确认索引存在。参见连接 AWS和安装。
来源
- Query — Amazon DynamoDB API Reference(2026-07-13 验证)
- Filter expressions for Query(2026-07-13 验证)
相关错误
- Query key condition not supported——键条件本身中有一个无效的运算符/形态。
- Query condition missed key schema element——查询没有提供分区键。
- 代码示例:Query in Node.js——键条件与过滤器正确拆分。
- 学习:Filtering strategies · Key condition expressions
参考资料
- Query — Amazon DynamoDB API Reference
- Filter expressions for Query — Amazon DynamoDB Developer Guide
- Using Global Secondary Indexes in DynamoDB — Amazon DynamoDB Developer Guide
最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。