由于 PostgreSQL 数据库上的 "duplicate" 索引,Liquibase 无法执行迁移

Liquibase fails to perform migration due to "duplicate" index on PostgreSQL database

我有一个 Liquibase 迁移作为我 Spring 引导应用程序的一部分来初始化我的数据库。出于开发目的,在 H2 内存数据库下,Liquibase 已毫无问题地执行了迁移。但是,当我 运行 它针对 PostgreSQL 数据库时,Liquibase 无法迁移为 PostgreSQL returns 以下内容:

Caused by: org.postgresql.util.PSQLException: ERROR: relation "idx_channel_id" already exists

请注意,正在应用索引的table是全新的,Liquibase迁移文件中没有其他同名索引。如果我删除这个索引创建,它只会在下一个索引创建时失败。如果我删除索引(或将它们移动到单独的迁移中,通过先决条件将其排除在调用 PostgreSQL 数据库之外),则迁移成功但根本没有索引。

我一直在为这个问题挠头,但我被困住了。下面是完整的 Liquibase 迁移:

databaseChangeLog:
  - changeSet:
      id: 1
      author: rmorrison
      changes:
        - createTable:
            tableName: shouts
            columns:
              - column:
                  name: id
                  type: bigint
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: discord_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: author_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: channel_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: guild_nickname
                  type: varchar(255)
                  constraints:
                    nullable: false
              - column:
                  name: content
                  type: varchar(2000)
                  constraints:
                    nullable: false
              - column:
                  name: created
                  type: blob
                  constraints:
                    nullable: false
        - createTable:
            tableName: contexts
            columns:
              - column:
                  name: id
                  type: bigint
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: discord_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: author_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: guild_nickname
                  type: varchar(255)
                  constraints:
                    nullable: false
              - column:
                  name: content
                  type: varchar(2000)
                  constraints:
                    nullable: false
              - column:
                  name: created
                  type: blob
                  constraints:
                    nullable: false
        - createTable:
            tableName: shouts_contexts
            columns:
              - column:
                  name: shout_id
                  type: bigint
                  constraints:
                    nullable: false
              - column:
                  name: context_id
                  type: bigint
                  constraints:
                    nullable: false
        - createIndex:
            indexName: idx_channel_id
            tableName: shouts
            unique: false
            columns:
              - column:
                  name: channel_id
                  type: varchar(18)
        - createIndex:
            indexName: idx_author_channel_id
            tableName: shouts
            unique: false
            columns:
              - column:
                  name: author_id
                  type: varchar(18)
              - column:
                  name: channel_id
                  type: varchar(18)
        - createIndex:
            indexName: idx_content
            tableName: shouts
            unique: true
            columns:
              - column:
                  name: content
                  type: varchar(2000)

编辑:我重新配置了 PostgreSQL 以启用语句日志记录,现在我看到了这一点——看起来这可能毕竟不是 Liquibase。继续调查...

< 2017-05-27 19:13:19.697 EDT > LOG:  execute <unnamed>: BEGIN
< 2017-05-27 19:13:19.698 EDT > LOG:  execute <unnamed>: CREATE TABLE public.shouts (id BIGSERIAL NOT NULL, discord_id VARCHAR(18) NOT NULL, author_id VARCHAR(18) NOT NULL, channel_id VARCHAR(18) NOT NULL, guild_nickname VARCHAR(255) NOT NULL, content VARCHAR(2000) NOT NULL, created OID NOT NULL, CONSTRAINT PK_SHOUTS PRIMARY KEY (id))
< 2017-05-27 19:13:19.718 EDT > LOG:  execute <unnamed>: CREATE TABLE public.contexts (id BIGSERIAL NOT NULL, discord_id VARCHAR(18) NOT NULL, author_id VARCHAR(18) NOT NULL, guild_nickname VARCHAR(255) NOT NULL, content VARCHAR(2000) NOT NULL, created OID NOT NULL, CONSTRAINT PK_CONTEXTS PRIMARY KEY (id))
< 2017-05-27 19:13:19.725 EDT > LOG:  execute <unnamed>: CREATE TABLE public.shouts_contexts (shout_id BIGINT NOT NULL, context_id BIGINT NOT NULL)
< 2017-05-27 19:13:19.727 EDT > LOG:  execute <unnamed>: CREATE INDEX idx_channel_id ON public.shouts(channel_id)
< 2017-05-27 19:13:19.727 EDT > ERROR:  relation "idx_channel_id" already exists
< 2017-05-27 19:13:19.727 EDT > STATEMENT:  CREATE INDEX idx_channel_id ON public.shouts(channel_id)
< 2017-05-27 19:13:19.741 EDT > LOG:  execute S_1: ROLLBACK

我解决了这个问题。事实证明,PostgreSQL 要求索引名称在 table 中是唯一的。我有一个 "backup" table,旧数据具有相同的索引名称,导致冲突。我删除了有问题的 table,现在迁移成功,没有问题。