如何在Liquibase中基于ID从CSV为现有表新增列并填充数据
问题描述
我有一张名为table1的表,初始结构及示例数据如下:
| Id | Column1 |
|---|---|
| 1 | abc |
| 2 | def |
我已通过以下Liquibase脚本为该表新增了column2列:
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd"> <changeSet id="add-date-column" author="gwylimwilliams"> <addColumn tableName="table1"> <column name="column2" type="date"> </column> </addColumn> </changeSet> </databaseChangeLog>
执行后table1结构变为:
| Id | Column1 | Column2 |
|---|---|---|
| 1 | abc | |
| 2 | def |
现在column2列全部为空,我需要基于Id从CSV文件中填充该列数据,且不能改动Column1的原有值。我尝试用loadData并通过skip跳过Column1,但不知道怎么实现基于Id的匹配,求最佳实现方案。我之前写的脚本如下:
<changeset author="gwylimwilliams" id="update-column"> <loadData file="abc.csv" separator="," tableName = "table1" > <column name="column1" type="skip"/> <column name="column2" type="datetime"/> </loadData> </changeset>
解决方案
要实现基于Id匹配填充column2,需要从CSV格式和Liquibase脚本两方面调整:
1. 调整CSV文件格式
CSV文件必须包含Id和column2两列数据,用来和数据库表中的Id做匹配,示例abc.csv内容如下:
Id,column2 1,2024-01-01 2,2024-02-01
2. 修改Liquibase脚本
使用loadData的updateMode属性设置为update,同时指定Id作为匹配的主键列,这样Liquibase会根据Id找到对应的行,只更新column2的值,不会影响Column1。修改后的脚本如下:
<changeSet author="gwylimwilliams" id="update-column"> <loadData file="abc.csv" separator="," tableName="table1" updateMode="update"> <!-- 开启更新模式,而非插入新行 --> <column name="Id" type="numeric"/> <!-- 指定Id列类型,用于匹配 --> <column name="Column1" type="skip"/> <!-- 跳过Column1,保留原有值 --> <column name="column2" type="date"/> <!-- 匹配后更新该列 --> </loadData> </changeSet>
关键说明
updateMode="update":告诉Liquibase当CSV中的Id在表中已存在时,执行更新操作而非插入新行。- 必须声明
Id列:Liquibase需要明确匹配依据列,所以要配置Id列并指定对应数据类型。 type="skip":确保Column1的原有数据不会被覆盖,完全保留原值。
内容的提问来源于stack exchange,提问作者jitendra varshney
相关产品推荐
相关产品推荐

