Liquibase通过CSV向H2插入数据时IDENTITY类型ID列报空值错误如何解决
H2数据库IDENTITY列配合Liquibase CSV导入空值报错解决方案
问题根因
报错是两个逻辑叠加导致的:
- Liquibase的
loadUpdateData需要依赖配置的primaryKey: id做数据匹配(匹配上就更新,没匹配上就插入),如果CSV中没有id列,Liquibase会默认给ID字段传入null值,而不会自动跳过该字段让数据库生成自增值。 - H2的IDENTITY主键自带非空约束,且只有INSERT语句未显式指定该列时才会触发自增逻辑,显式传入
null会直接触发非空约束报错。
解决方案
方案1:省略CSV中的ID列,完全依赖数据库自增
修改changeset配置,明确声明ID列是数据库自动计算生成的,不需要Liquibase传值,修改后的yaml配置如下:
- changeSet: id: 2021-10-05--0001-data-genres author: nsnikolskiy runOnChange: true loadUpdateData: primaryKey: id file: db/changeLog/data/data/2021-10-04--0001-genres.csv relativeToChangeLog: true separator: ; quotChar: '"' encoding: UTF-8 tableName: GENRE columns: - column: name: ID type: COMPUTED - column: name: NAME header: name
对应CSV可以只保留业务字段:
name comedy tradegy drama action novel horror satira poetry detective fairy-tale
方案2:保留CSV中的ID列(推荐)
如果需要用loadUpdateData做存量数据的更新匹配,保留CSV中的ID列是更稳定的方案:自增ID作为主键匹配的准确率远高于业务字段(比如NAME可能出现重复、修改的情况),你当前显式填写ID的用法本身就是符合loadUpdateData设计逻辑的最优实现。
内容的提问来源于stack exchange,提问作者Nikolay Nickolskiy
相关产品推荐
相关产品推荐

