DuplicateItemException: duplicate primary key

요약 — 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과 정반대의 기본값입니다. INSERT가 중복 키에서 실패하기를 기대하며 SQL에서 왔다면 이것이 바로 그 동작입니다. upsert 시맨틱을 기대했다면 이 오류가 놀라움입니다.

왜 발생하나요

  • 항목이 진짜 이미 존재함 — 재시도, 재생, 또는 같은 키에서 경합하는 두 작성자가 모두 INSERT를 실행.
  • 생성이 아니라 업데이트를 원했음PutItem 스타일 코드를 PartiQL로 이식하며 INSERT가 교체한다고 가정.
  • 멱등하지 않은 재시도 루프 — 첫 시도는 성공했지만 응답이 손실되어(타임아웃) 재시도가 같은 키를 다시 삽입.
  • 고유하지 않은 합성 키 — 구성한 파티션/정렬 키가 생각보다 자주 충돌(예: 초 단위 정밀도의 타임스탬프).

어떻게 고치나요

  1. 기존 항목을 업데이트하나요? UPDATE를 사용하세요:

    UPDATE "orders" SET status = 'shipped' WHERE pk = 'ORDER#123' AND sk = 'META'
  2. 존재-시-교체(PutItem 시맨틱)를 원하나요? PutItem을 호출하세요 — PartiQL에는 upsert 문이 없고, 네이티브 API의 기본값이 바로 원하는 그 덮어쓰기입니다:

    await client.send(new PutItemCommand({TableName: 'orders', Item: item}));
  3. 생성이 멱등할 때는 성공으로 취급하세요 — 첫 시도가 이미 쓴 항목에 대해 재시도가 DuplicateItemException을 맞으면, 이를 catch하고 무시하는 것이 종종 올바른 처리입니다.

  4. 고유성에 의존할 때는 INSERT를 유지하세요 — 예외는 생성 전용 가드이며, PutItem 조건의 attribute_not_exists()에 해당하는 PartiQL 등가물입니다.

실제 데이터에 대해 문을 시도하는 것이 INSERT/UPDATE 구분을 체득하는 가장 빠른 방법입니다 — DynoTable 데스크톱 앱은 라이브 테이블에 대해 SQL 워크벤치에서 PartiQL을 실행하고, DynamoDB Expression Builder는 대신 PutItem 시맨틱이 필요할 때 동등한 네이티브 API 요청을 내보냅니다.

관련 오류

References

공식 AWS 문서(위 링크)를 기준으로 2026-07-13에 마지막으로 검증되었습니다.

Console 없이 DynamoDB 작업하기

DynoTable은 DynamoDB를 위한 빠른 데스크톱 클라이언트입니다 — 테이블을 탐색하고, SQL 스타일 쿼리를 실행하고, 항목을 로컬에서 편집하세요.