DuplicateItemException: duplicate primary key
TL;DR — Ein PartiQL INSERT ist ein striktes Create: Wenn ein Item mit demselben Primärschlüssel bereits existiert, wirft DynamoDB DuplicateItemException, statt es zu überschreiben. Um das bestehende Item zu ändern, nutze PartiQL UPDATE; um PutItems Replace-if-exists-Semantik zu bekommen, nutze PutItem selbst — PartiQL INSERT ersetzt bewusst nie.
Was es bedeutet
DuplicateItemException: There was an attempt to insert an item with the
same primary key as an item that already exists in the DynamoDB table.Die PartiQL-Data-Plane (ExecuteStatement / ExecuteTransaction / BatchExecuteStatement) bildet INSERT auf ein bedingtes Create ab — es gelingt nur, wenn kein Item mit diesem Primärschlüssel existiert. Das ist der entgegengesetzte Default zum nativen PutItem, das ein bestehendes Item stillschweigend ersetzt. Wenn du von SQL kommst und erwartest, dass INSERT bei einem doppelten Key fehlschlägt, ist das genau dieses Verhalten; wenn du Upsert-Semantik erwartet hast, ist dieser Fehler die Überraschung.
Warum es passiert
- Das Item existiert tatsächlich bereits — ein Retry, ein Replay oder zwei Writer, die auf demselben Key um die Wette laufen und beide
INSERTabsetzen. - Du wolltest ein Update, kein Create —
PutItem-artigen Code auf PartiQL portiert und angenommen, dassINSERTersetzt. - Eine nicht-idempotente Retry-Schleife — der erste Versuch gelang, aber die Antwort ging verloren (Timeout), und der Retry fügt denselben Key erneut ein.
- Ein synthetischer Key, der nicht eindeutig ist — der zusammengesetzte Partition-/Sort-Key kollidiert öfter, als du denkst (z. B. ein Zeitstempel mit Sekundengenauigkeit).
So behebst du es
Ein bestehendes Item aktualisieren? Nutze
UPDATE:UPDATE "orders" SET status = 'shipped' WHERE pk = 'ORDER#123' AND sk = 'META'Replace-if-exists gewünscht (PutItem-Semantik)? Rufe
PutItemauf — PartiQL hat kein Upsert-Statement, und der Default der nativen API ist genau das Überschreiben, das du willst:await client.send(new PutItemCommand({TableName: 'orders', Item: item}));Behandle es als Erfolg, wenn das Create idempotent ist — wenn ein Retry auf
DuplicateItemExceptionfür ein Item trifft, das dein erster Versuch bereits geschrieben hat, ist Abfangen und Ignorieren oft die korrekte Behandlung.Behalte
INSERT, wenn du dich auf Eindeutigkeit verlässt — die Exception ist dein Create-only-Guard, das PartiQL-Äquivalent zuattribute_not_exists()auf einerPutItem-Bedingung.
Statements gegen echte Daten auszuprobieren ist der schnellste Weg, die INSERT/UPDATE-Aufteilung zu verinnerlichen — DynoTables PartiQL-Editor führt Statements mit Inline-Diagnosen und Quick-Fixes gegen deine Live-Tabellen aus, und der DynamoDB Expression Builder gibt die äquivalenten nativen API-Anfragen aus, wenn du stattdessen PutItem-Semantik brauchst.
So reproduzierst du es
Ein PartiQL INSERT für einen Primärschlüssel, der bereits existiert:
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'}`
})
);Echte Ausgabe:
DuplicateItem: Duplicate primary key exists in table
HTTP 400Wissenswert, wenn du lokal testest: DynamoDB Local zeigt das als DuplicateItem mit der kurzen Meldung oben, während die Service-API-Referenz es als DuplicateItemException mit einem längeren Satz dokumentiert. Gleiche auf HTTP 400 plus die Operation ab, nicht auf den exakten Namen oder Wortlaut, sonst verhält sich dein Handler gegen Local anders als gegen die echte Tabelle.
Verwandte Fehler
- ConditionalCheckFailedException — der native-API-Zwilling:
attribute_not_exists()-Guard, der beiPutItemfehlschlägt. - ValidationException: Unexpected from source — die andere häufige PartiQL-Abweisung.
- Lernen: PartiQL-Beispiele · PartiQL vs. SQL
Referenzen
- ExecuteStatement — Amazon DynamoDB API Reference (DuplicateItemException)
- PartiQL insert statements for DynamoDB — Developer Guide
- PartiQL update statements for DynamoDB — Developer Guide
Zuletzt verifiziert am 2026-07-13 gegen die oben verlinkte offizielle AWS-Dokumentation.
Am 2026-07-26 gegen DynamoDB Local 2.x mit dem AWS SDK for JavaScript v3.1095.0 reproduziert — die Ausgabe oben ist wortgetreu.