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: pk

FilterExpression 在項目被讀取之後執行,用來丟棄你不想要的行;KeyConditionExpression之前執行,用來按鍵選擇讀取哪些項目。在過濾器中引用分割區索引鍵/排序索引鍵混淆了這些角色,因此 DynamoDB 以一個 HTTP 400 ValidationException 拒絕它——屬於用戶端錯誤,在你重構之前不可重試

為什麼會發生

  • 把鍵條件寫成了過濾器——FilterExpression: 'sk = :v',其中 sk 是排序索引鍵;它屬於 KeyConditionExpression
  • 對索引的鍵做過濾——當你 Query 一個 GSI/LSI 時,那個索引自己的分割區索引鍵/排序索引鍵對本次查詢而言就是"主索引鍵屬性",不能出現在過濾器中。
  • 把一個 scan 過濾器複製貼上到一個 query 上,而其中一個被過濾的屬性恰好是鍵。
  • 試圖透過過濾器為排序索引鍵新增第二個條件(例如一個範圍),而不是在鍵條件中表達它。

如何修正

  1. 把鍵條件移入 KeyConditionExpression
    KeyConditionExpression: 'pk = :pk AND begins_with(sk, :prefix)',
    // FilterExpression: only NON-key attributes, e.g. 'status = :active'
  2. 使用正確的索引。 如果你需要在一個非鍵屬性上過濾/選擇,就把它建模為某個 GSI 的分割區索引鍵/排序索引鍵並按鍵查詢那個索引。
  3. 讓過濾器只用於非鍵屬性——它會裁剪結果,但仍然會為掃描到的每個項目消耗讀取容量,因此要依靠鍵/索引來做選擇。
  4. 在查詢 GSI? 記住它的鍵屬性在過濾器裡同樣禁用——在鍵條件中對它們做條件。

在 DynoTable 中執行

DynoTable 的查詢面板將關鍵條件和過濾器保留在單獨的欄位中 - 分割槽和排序索引鍵約束永遠不會落在 FilterExpression 中。用⌘K開啟一張表,設定關鍵條件,然後新增非關鍵過濾器;將生成的請求複製到你的 SDK 中。使用 Query Builder 原型 GSI 查詢,其中索引鍵必須保留在 KeyConditionExpression 中。使用 ⌘P 切換設定檔案;在“設定”→“設定檔案”上Test Connection,確認索引存在。參見連線 AWS安裝

來源

相關錯誤

參考資料

最後核實於 2026-07-13,依據上方連結的 AWS 官方文件。

不必透過主控台就能操作 DynamoDB

一款快速的 DynamoDB 桌面用戶端,可執行 DynamoDB 無法執行的真正 SQL — JOINs、GROUP BY、聚合 — 並支援視覺化編輯與使用你自己的 Bedrock 金鑰的 AI 代理。

30 天免費試用,無需信用卡 — 之後為無時間限制的免費方案。