DuplicateItemException:重複的主索引鍵
TL;DR — PartiQL 的 INSERT 是嚴格的建立:如果已經存在具有相同主索引鍵的項目,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 對應成有條件的建立 — 只有在不存在具有該主索引鍵的項目時才會成功。這與原生 PutItem 的預設相反,後者會靜默地取代既有項目。如果你來自 SQL、預期 INSERT 在鍵重複時失敗,那這正是那個行為;如果你預期的是 upsert 語意,這個錯誤就是意外。
為什麼會發生
- 項目確實已經存在 — 一次重試、一次重播,或兩個寫入者在同一個鍵上競賽而都發出了
INSERT。 - 你想要的是更新而不是建立 — 把
PutItem風格的程式碼移植到 PartiQL,並假設INSERT會取代。 - 非冪等的重試迴圈 — 第一次嘗試成功了但回應遺失(逾時),而重試又重新插入同一個鍵。
- 合成的鍵並不唯一 — 你組出來的分割區/排序索引鍵碰撞的機率比你以為的高(例如精確度只到秒的時間戳)。
如何修正
要更新既有項目?使用
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— 這個例外就是你的「只建立」防護,相當於 PartiQL 版本的PutItem條件式attribute_not_exists()。
要內化 INSERT/UPDATE 的區別,最快的方法就是拿真實資料試跑陳述式 — DynoTable 的 PartiQL 編輯器可對你的線上資料表執行陳述式並提供行內診斷與快速修正,而當你需要 PutItem 語意時,DynamoDB Expression Builder 會產出等價的原生 API 請求。
重現方式
對一個已存在的主索引鍵執行 PartiQL INSERT:
await client.send(
new PutItemCommand({
TableName: 'orders',
Item: {pk: {S: 'ORDER#1'}, sk: {S: 'META'}}
})
);
await client.send(
new ExecuteStatementCommand({
Statement: `INSERT INTO "orders" VALUE {'pk':'ORDER#1','sk':'META'}`
})
);實際輸出:
DuplicateItem: Duplicate primary key exists in table
HTTP 400如果你在本機測試,這點值得知道:DynamoDB Local 會以 DuplicateItem 加上方那句簡短訊息呈現,而服務端的 API 參考文件則記載為 DuplicateItemException 並附上較長的句子。請比對 HTTP 400 加上操作本身,而不是確切的名稱或用字,否則你的處理程式在 Local 與真實資料表上的行為會不一樣。
相關錯誤
- ConditionalCheckFailedException — 原生 API 的孿生兄弟:
PutItem上的attribute_not_exists()防護失敗。 - ValidationException: Unexpected from source — 另一種常見的 PartiQL 拒絕。
- 學習:PartiQL 範例 · PartiQL 與 SQL 比較
參考資料
- ExecuteStatement — Amazon DynamoDB API Reference (DuplicateItemException)
- PartiQL insert statements for DynamoDB — Developer Guide
- PartiQL update statements for DynamoDB — Developer Guide
最後於 2026-07-13 對照上方連結的官方 AWS 文件驗證。
已於 2026-07-26 對照 DynamoDB Local 2.x 與 AWS SDK for JavaScript v3.1095.0 重現 — 上方輸出為逐字原文。