DuplicateItemException: duplicate primary key
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 examples · PartiQL vs 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 复现——上方输出为原样照录。