DuplicateItemException: duplicate primary key

TL;DR — Um INSERT do PartiQL é uma criação estrita: se um item com a mesma chave primária já existe, o DynamoDB lança DuplicateItemException em vez de sobrescrevê-lo. Para modificar o item existente use o UPDATE do PartiQL; para obter a semântica de substituir-se-existir do PutItem, use o próprio PutItem — o INSERT do PartiQL deliberadamente nunca substitui.

O que significa

DuplicateItemException: There was an attempt to insert an item with the
same primary key as an item that already exists in the DynamoDB table.

O data-plane do PartiQL (ExecuteStatement / ExecuteTransaction / BatchExecuteStatement) mapeia INSERT para uma criação condicional — ele só é bem-sucedido quando nenhum item com aquela chave primária existe. Esse é o padrão oposto do PutItem nativo, que substitui um item existente silenciosamente. Se você veio do SQL esperando que INSERT falhe em uma chave duplicada, este é exatamente esse comportamento; se você esperava semântica de upsert, este erro é a surpresa.

Por que acontece

  • O item genuinamente já existe — um retry, um replay, ou dois processos de escrita competindo na mesma chave ambos emitindo INSERT.
  • Você queria uma atualização, não uma criação — portar código no estilo PutItem para o PartiQL e supor que INSERT substitui.
  • Um loop de retry não idempotente — a primeira tentativa foi bem-sucedida mas a resposta foi perdida (timeout), e o retry reinsere a mesma chave.
  • Uma chave sintética que não é única — a chave de partição/ordenação que você compõe colide mais frequentemente do que você imagina (por exemplo, um timestamp com precisão de segundos).

Como corrigir

  1. Atualizando um item existente? Use UPDATE:

    UPDATE "orders" SET status = 'shipped' WHERE pk = 'ORDER#123' AND sk = 'META'
  2. Quer substituir-se-existir (semântica do PutItem)? Chame PutItem — o PartiQL não tem instrução de upsert, e o padrão da API nativa é exatamente a sobrescrita que você busca:

    await client.send(new PutItemCommand({TableName: 'orders', Item: item}));
  3. Trate como sucesso quando a criação é idempotente — se um retry encontra DuplicateItemException para um item que sua primeira tentativa já escreveu, capturá-lo e ignorá-lo é frequentemente o tratamento correto.

  4. Mantenha o INSERT quando você depende da unicidade — a exceção é seu guard de somente-criação, o equivalente no PartiQL de attribute_not_exists() em uma condição de PutItem.

Testar instruções contra dados reais é a forma mais rápida de internalizar a divisão INSERT/UPDATE — o app desktop DynoTable roda PartiQL em um workbench SQL contra suas tabelas ao vivo, e o DynamoDB Expression Builder emite as requisições equivalentes da API nativa quando você precisa da semântica de PutItem em vez disso.

Erros relacionados

Referências

Verificado pela última vez em 2026-07-13 contra a documentação oficial da AWS vinculada acima.

Trabalhe com o DynamoDB sem o Console

O DynoTable é um cliente desktop rápido para o DynamoDB — navegue pelas tabelas, execute consultas no estilo SQL e edite itens localmente.