DBeaver报Duplicate entry是主键/唯一约束冲突,非解析错误;需在“设置”页(列映射后、“完成”前)选择“忽略冲突”跳过重复行或“更新现有记录”覆盖旧数据,而非默认“仅插入”。

DBeaver 报 Duplicate entry,说明主键或唯一约束已存在相同值,不是文件解析错误,而是写入策略没选对。
导入向导里怎么选“跳过重复”或“覆盖更新”
这个选项不在第一步的文件选择页,而是在列映射之后、点击“完成”前的“设置”页(不同版本叫法略有差异:可能是“目标设置”“写入选项”或“冲突处理”)。默认是“仅插入”,遇到重复就报 Duplicate entry 或 unique_violation。
- 想保留已有数据、只导入新记录 → 选
忽略冲突(部分版本显示为Skip duplicates) - 想用新数据覆盖旧记录 → 选
更新现有记录(PostgreSQL 对应生成ON CONFLICT DO UPDATE,MySQL 对应ON DUPLICATE KEY UPDATE) - 想彻底重刷整表 → 先手动清空目标表,再用默认“仅插入”方式导入,避免策略误配
注意:忽略冲突 不会报错中断,但也不会告诉你哪几行被跳过了——结果页的“跳过行数”要手动点开看;更新现有记录 要求源 CSV 必须包含所有待更新字段,否则未映射的字段会被设为 NULL。
为什么勾了“忽略错误”还是报错中断
很多人混淆两个开关:“忽略错误”(Ignore errors)和“忽略冲突”(Skip duplicates)。前者控制是否跳过类型转换失败、空值违规等运行时错误;后者才专门处理主键/唯一键重复。如果只开了“忽略错误”,但没改写入策略,Duplicate entry 依然会触发中断。
- 检查导入向导最后一页的选项组,确认你改的是“冲突处理”相关下拉菜单,不是顶部的全局错误开关
- MySQL 用户注意:DBeaver 的
INSERT IGNORE模式在部分驱动版本中不生效,可临时改用 SQL 执行模式,手写INSERT IGNORE INTO ... - PostgreSQL 用户注意:若目标表无主键但有唯一索引,需在“冲突处理”里手动指定索引字段,否则
ON CONFLICT无法命中
如何提前知道哪些主键会冲突
别等导入跑完再翻日志。在导入前用一条 SQL 快速探查:
SELECT COUNT(*) FROM target_table WHERE id IN (SELECT id FROM csv_import_temp);
实际操作分三步:
- 先用 DBeaver 的“导入数据”功能,把 CSV 临时导入到一个同结构的
temp_table(不设主键) - 执行上面的 SQL,看返回数是否大于 0
- 再查具体冲突值:
SELECT id FROM temp_table INTERSECT SELECT id FROM target_table;
这样能提前判断重复规模,决定该用“忽略”还是“更新”,而不是靠盲试。
执行 SQL 文件时也报 Duplicate entry 怎么办
这是另一条路径:不是走“导入数据”向导,而是右键执行 SQL 文件。此时 DBeaver 默认逐条执行,一条失败就停。解决方法在执行设置里:
- 勾选
Execute batches(启用批处理) - 取消勾选
Stop on error(出错不停止) - SQL 文件里每条
INSERT前加上INSERT IGNORE(MySQL)或包装成INSERT ... ON CONFLICT DO NOTHING(PostgreSQL)
注意:Stop on error 关闭后,错误仍会记录在执行日志里,但不会中断后续语句——这和导入向导里的“忽略冲突”逻辑不同,别混用。
真正容易被忽略的是:主键冲突的判定粒度取决于你定义的约束本身。比如联合唯一索引(UNIQUE (user_id, action)),DBeaver 的冲突检测只会比对这两个字段组合,而不是单看 user_id。策略选错,问题就藏得更深。











