DuplicateItemException: duplicate primary key
TL;DR — PartiQL INSERT 是嚴格的建立:若已存在相同 primary key 的項目,DynamoDB 會拋出 DuplicateItemException 而非覆寫它。要修改既有項目請用 PartiQL UPDATE;要取得 PutItem 的「存在即替換」語義,請用 PutItem 本身 — PartiQL INSERT 刻意永不替換。
這是什麼意思
DuplicateItemException: There was an attempt to insert an item with the
same primary key as an item that already exists in the DynamoDB table.PartiQL 資料平面(ExecuteStatement / ExecuteTransaction / BatchExecuteStatement)將 INSERT 對應為條件式建立 — 只有在不存在該 primary key 的項目時才成功。這與原生 PutItem 的預設相反,後者會默默替換既有項目。若你來自 SQL 且預期 INSERT 在重複鍵時失敗,這正是那種行為;若你預期 upsert 語義,這個錯誤就是意外。
為什麼會發生
- 項目確實已經存在 — 重試、重播,或兩個寫入者在同一個鍵上競爭而都發出
INSERT。 - 你想要的是更新,而非建立 — 將
PutItem風格的程式碼移植到 PartiQL 並假設INSERT會替換。 - 非冪等的重試迴圈 — 第一次嘗試成功但回應遺失(逾時),而重試重新插入了相同的鍵。
- 不唯一的合成鍵 — 你組合的 partition/sort key 比你想的更常碰撞(例如以秒為精度的時間戳)。
如何修正
要更新既有項目?用
UPDATE:UPDATE "orders" SET status = 'shipped' WHERE pk = 'ORDER#123' AND sk = 'META'想要存在即替換(PutItem 語義)?呼叫
PutItem— PartiQL 沒有 upsert 語句,而原生 API 的預設正是你想要的覆寫:await client.send(new PutItemCommand({TableName: 'orders', Item: item}));當建立是冪等時將它視為成功 — 若重試對一個你第一次嘗試已寫入的項目碰到
DuplicateItemException,捕捉並忽略它往往是正確的處理方式。當你依賴唯一性時保留
INSERT— 這個例外就是你的僅建立防護,等同於PutItem條件上的attribute_not_exists()。
對真實資料嘗試語句是內化 INSERT/UPDATE 之別最快的方式 — DynoTable 桌面應用程式在 SQL workbench 中對你的即時表格執行 PartiQL,而當你需要 PutItem 語義時,DynamoDB Expression Builder 會產出等效的原生 API 請求。
相關錯誤
- ConditionalCheckFailedException — 原生 API 的雙生:
PutItem上的attribute_not_exists()防護失敗。 - ValidationException: Unexpected from source — 另一個常見的 PartiQL 拒絕。
- 學習:PartiQL examples · PartiQL vs SQL
References
- ExecuteStatement — Amazon DynamoDB API Reference (DuplicateItemException)
- PartiQL insert statements for DynamoDB — Developer Guide
- PartiQL update statements for DynamoDB — Developer Guide
最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。