如何在PostgreSQL已有数据的表中通过Liquibase添加自增主键列
错误原因
你遇到的报错是因为执行顺序逻辑问题:你先声明新增非空的id列,此时表中已有存量数据的id字段会被默认赋值为NULL,直接触发非空约束报错,执行流程还未到后续添加自增属性的步骤就被中断。
最优解决方案
直接在新增列时同时声明自增属性和主键约束,Liquibase会自动适配PostgreSQL语法,给所有历史行填充递增的序列值,无需清空现有数据。正确的changeSet配置如下:
<changeSet id="added_pk"> <addColumn tableName="table" schemaName="schema"> <column name="id" type="bigint" autoIncrement="true"> <constraints primaryKey="true" nullable="false" primaryKeyName="PK_TABLE_ID"/> </column> </addColumn> </changeSet>
该配置会自动完成以下操作:
- 为
id列创建匹配bigint类型的自增序列 - 给表中所有已有历史行按顺序填充1、2、3……的非空id值
- 为
id列添加主键约束,后续新插入数据也会自动生成自增id
拆分步骤实现方案
如果你有自定义序列规则等特殊需求,需要拆分步骤实现,可以参考以下配置:
<changeSet id="added_pk_step1"> <!-- 先新增允许为空的id列,避免存量数据触发非空约束 --> <addColumn tableName="table" schemaName="schema"> <column name="id" type="bigint"/> </addColumn> </changeSet> <changeSet id="added_pk_step2"> <!-- 为id列添加自增属性,自动回填已有行的id值 --> <addAutoIncrement columnDataType="bigint" columnName="id" tableName="table" schemaName="schema" incrementBy="1" startWith="1"/> <!-- 回填完成后添加非空和主键约束 --> <addPrimaryKey columnNames="id" tableName="table" schemaName="schema" constraintName="PK_TABLE_ID"/> </changeSet>
内容的提问来源于stack exchange,提问作者davide.ferrari
相关产品推荐
相关产品推荐

