为何Flyway脚本向PostgreSQL 10.0插入数据时触发唯一键冲突?
解决Flyway插入PostgreSQL数据时的唯一键约束冲突问题
嘿,咱们来一步步拆解你遇到的这个问题:你运行Flyway脚本V1.1.2__insert_candy.sql插入数据时,触发了“唯一键值违反唯一约束”的错误,但从你给出的表创建语句来看,只有id字段是主键(自带唯一约束)。下面是几个最可能的原因和排查方法:
1. 检查是否存在隐藏的唯一约束
虽然你提供的建表语句里只定义了id为主键,但很可能后续通过ALTER TABLE给candy或name字段加了唯一约束(比如业务上要求糖果编码或名称不能重复)。你可以用这条SQL查询表上所有的唯一约束:
SELECT conname, pg_get_constraintdef(c.oid) FROM pg_constraint c JOIN pg_class t ON c.conrelid = t.oid WHERE t.relname = 'candy' AND contype IN ('p', 'u');
如果结果里出现了针对candy或name字段的约束,那就是它导致了冲突。
2. 确认序列与表中ID是否同步
你没在插入语句里指定id,用的是序列candy_id_seq的自增值,但如果序列的当前值落后于表中已有的最大id,就会生成重复的id触发主键约束。你可以这样检查:
-- 查看表中已有的最大ID SELECT MAX(id) FROM candy; -- 查看序列当前的取值 SELECT currval('candy_id_seq');
如果序列值小于表中最大ID,就需要重置序列:
SELECT setval('candy_id_seq', (SELECT MAX(id) FROM candy) + 1);
3. 检查Flyway的脚本执行历史
有可能这个脚本之前已经成功执行过,Flyway的元数据表flyway_schema_history里已经记录了该版本的执行记录,不过Flyway默认会跳过已执行的版本——除非你手动修改过元数据或者执行过clean操作。你可以查一下:
SELECT version, description, success FROM flyway_schema_history WHERE version = '1.1.2';
快速验证冲突数据
你也可以直接查询表中是否已经存在要插入的数据,或者序列即将生成的ID是否已存在:
-- 检查candy字段是否已有BUTTERCUP SELECT * FROM candy WHERE candy = 'BUTTERCUP'; -- 检查name字段是否已有Peanut Butter Cup SELECT * FROM candy WHERE name = 'Peanut Butter Cup'; -- 检查序列下一个ID是否已存在(执行后序列会自增一次,注意) SELECT * FROM candy WHERE id = nextval('candy_id_seq');
按照上面的步骤排查,应该就能快速定位到问题所在啦!
内容的提问来源于stack exchange,提问作者Jeremiah Muela
相关产品推荐
相关产品推荐

