为什么从Flyway简单插入Postgres导致重复键值违反?

时间:2018-03-19 17:40:21

标签: postgresql flyway

当我运行我的flyway脚本插入PostgreSQL 10.0中的表时,我得到一个重复的键值违反了唯一约束,我无法理解为什么

SQL(V1.1.2__insert_candy.sql)

insert into candy(candy, name) values ('BUTTERCUP','Peanut Butter Cup')

CREATE SEQUENCE candy_id_seq;
CREATE TABLE candy
(
  id            int primary key not null default nextval('candy_id_seq'),
  name          text not null,
  candy         text,
  last_modified timestamp with time zone default now()
);

表值

id  name             candy            last_modified
1   Sucker           SUCKER           2018-01-26 00:28:36.763462
2   Peanut Brittle   PEANUT_BRITTLE   2018-01-26 00:28:36.763462
3   Chocolate Cream  CHOCOLATE_CREAM  2018-01-26 00:28:36.763462
4   S'mores          SMORES           2018-01-26 00:28:37.418496
5   Candy Apple      CANDY_APPLE      2018-01-26 00:28:38.464321
6   Carmel Apple     CARMEL_APPLE     2018-01-26 00:28:38.998292
7   Sugar Free       SUGAR_FREE       2018-01-26 00:28:39.225477

有错误

Error creating bean with name 'flywayInitializer' defined in class path resource 
dbsupport.FlywaySqlScriptException: 
Migration V1.1.2__insert_candy.sql failed
--------------------------------------------------------------
SQL State  : 23505
Error Code : 0
Message    : ERROR: duplicate key value violates unique constraint "candy_pkey"
  Detail: Key (id)=(7) already exists.
Line       : 1
Statement  : insert into candy(candy, name) values ('BUTTERCUP','Peanut Butter Cup')

如果我直接运行声明,一切正常。

当我删除手动插入的行时,我可以毫无问题地运行flyway脚本。

1 个答案:

答案 0 :(得分:1)

在@Karol Dowbecki的评论之后,我检查了序列(我甚至不知道这是一件事)

sequence_name | last_value | start_value | increment_by |      max_value      | min_value | cache_value | log_cnt | is_cycled | is_called 
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
candy_id_seq   |          6 |           1 |            1 | 9223372036854775807 |         1 |           1 |      27 | f         | t
(1 row)

确定ID序列是6而不是7。

INSERT INTO candy
SELECT 7, 'Sugar Free', 'SUGAR_FREE'
WHERE NOT EXISTS (select 1 from candy where candy.candy = 'SUGAR_FREE');

这是由某人在插入前一个飞路脚本上明确指定ID

引起的
SELECT pg_catalog.setval('candy_id_seq', 7, true);

要解决此问题,我将其添加到我的飞路脚本

{{1}}

我仍然觉得这有点冒险,因为我明确地设置了candy_id_seq,但它会让我重新开始。

感谢您的帮助。