由于 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,现在迁移成功,没有问题。
我有一个 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,现在迁移成功,没有问题。