DynamoDB GSI does not project the requested attribute

TL;DR — 你查询了一个全局二级索引并(通过 ProjectionExpressionSelect=ALL_ATTRIBUTES)请求了一个索引未投影的属性。一个 GSI 只返回它自己的键属性、基础表的键属性,以及你在它的投影中列出的内容——别无其他。要么把请求收窄到已投影的属性,要么把该属性添加到 GSI 的投影,要么按主键查询基础表。

含义

ValidationException: One or more parameter values were invalid: Global secondary
index <index_name> does not project <attribute_name>

# or, with Select=ALL_ATTRIBUTES on a KEYS_ONLY / INCLUDE index:
ValidationException: Select type ALL_ATTRIBUTES is not supported for global
secondary index <index_name> because its projection type is not ALL

# what the engine actually returns, reproduced against DynamoDB Local:
ValidationException: One or more parameter values were invalid: Global secondary index gsi1 does not project [unprojected]

与本地二级索引(它可以额外付费从基础项目取回未投影的属性)不同,一个 GSI 是一份自包含的副本。它在物理上只存储其投影中的属性——AWS 自己的文档直言不讳:"global secondary index queries cannot fetch attributes from the base table。" 向一个 GSI 查询请求那个集合之外的任何东西都是无法满足的,因此 DynamoDB 拒绝该请求(一个 ValidationException,HTTP 400——不可重试),而不是悄悄返回部分数据。

为什么会发生

  • ProjectionType: KEYS_ONLY 索引被查询了一个非键属性。
  • ProjectionType: INCLUDE 索引被查询了一个不在 NonKeyAttributes 列表中的属性。
  • Select: ALL_ATTRIBUTES 用在一个不是 ProjectionType: ALL 的 GSI 上。
  • 假定 LSI 行为——期望一个 GSI 从基础表取回未投影的属性(只有 LSI 才这样做)。
  • 一个投影随着访问模式的演变而偏离了查询的需求。

如何修复

  1. 只请求已投影的属性——把 ProjectionExpression 限制在 GSI 的键 + 它的已投影集合,或者去掉 Select: ALL_ATTRIBUTES
  2. 把该属性添加到 GSI 投影——对于一个新属性,用 ProjectionType: INCLUDE(把它列出)或 ALL 创建/替换 GSI。现有 GSI 的投影无法就地编辑;你需要添加一个新的 GSI 或重新创建它。
  3. 从基础表取回——用 GSI _确实_返回的键,对基础表做一次 GetItem/BatchGetItem 以获取完整项目。
  4. 使用 ProjectionType: ALL,如果你经常需要索引的每个属性(接受额外的存储/写入成本)。

想在查询一个 GSI 之前看看它实际携带哪些属性?DynoTable 桌面应用会显示每个索引的投影,让你只请求那里有的东西——没有 does not project 的意外。

相关错误

参考资料

最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

一款快速的 DynamoDB 桌面客户端,可运行 DynamoDB 无法执行的真正 SQL——JOINs、GROUP BY、聚合——并支持可视化编辑和运行在你自己的 Bedrock 密钥上的 AI agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。