Liquibase generateChangeLog:单次执行如何排除部分数据并保留全量DDL?
解决Liquibase generateChangeLog排除大表数据但保留全量DDL的问题
这个问题我之前帮不少开发者解决过——Liquibase的diffExcludeObjects/diffIncludeObjects确实是针对整个数据库对象(包括DDL和数据)的过滤,没法单独只排除数据部分。不过通过拆分三个步骤,完全可以实现「保留全量表结构+仅导出指定小表数据」的需求,具体操作如下:
步骤1:生成仅包含全量DDL的基础变更日志
首先我们需要导出所有表的结构,完全不包含任何数据。可以通过generateChangeLog目标搭配excludeData=true参数实现,这样Liquibase只会生成表、索引、约束等DDL语句,跳过所有数据导出。
Maven插件配置示例:
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>你的Liquibase版本号</version> <configuration> <changeLogFile>src/main/resources/changelog/ddl-only-changelog.xml</changeLogFile> <url>jdbc:xxx://你的数据库地址</url> <username>数据库用户名</username> <password>数据库密码</password> <excludeData>true</excludeData> <!-- 关键:跳过所有数据导出 --> </configuration> <executions> <execution> <id>generate-full-ddl</id> <goals> <goal>generateChangeLog</goal> </goals> </execution> </executions> </plugin>
执行这个配置后,你会得到一个只包含所有表结构的变更日志文件。
步骤2:生成指定小表的数据变更日志
接下来我们单独导出需要保留数据的小表,同时确保不会重复生成DDL。这里需要用到diffTypes=data参数(指定只对比/导出数据),再配合diffIncludeObjects(指定要导出数据的表)或者diffExcludeObjects(排除大表)来过滤目标表。
Maven插件配置示例(以指定小表为例):
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>你的Liquibase版本号</version> <configuration> <changeLogFile>src/main/resources/changelog/data-only-changelog.xml</changeLogFile> <url>jdbc:xxx://你的数据库地址</url> <username>数据库用户名</username> <password>数据库密码</password> <diffTypes>data</diffTypes> <!-- 关键:只处理数据部分,不生成DDL --> <diffIncludeObjects>table:small_table_1,table:small_table_2</diffIncludeObjects> <!-- 指定要导出数据的表 --> <!-- 如果是排除大表,替换成:<diffExcludeObjects>table:large_table_1,table:large_table_2</diffExcludeObjects> --> </configuration> <executions> <execution> <id>generate-target-data</id> <goals> <goal>generateChangeLog</goal> </goals> </execution> </executions> </plugin>
执行后会得到一个只包含指定表数据插入语句的变更日志,不会有任何DDL重复。
步骤3:合并两个变更日志
最后创建一个主变更日志文件,通过<include>标签把前面生成的DDL和数据日志合并起来,这样执行Liquibase更新时会先创建所有表结构,再插入指定表的数据。
主变更日志示例:
<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-latest.xsd"> <!-- 先执行全量DDL --> <include file="changelog/ddl-only-changelog.xml"/> <!-- 再执行指定表的数据插入 --> <include file="changelog/data-only-changelog.xml"/> </databaseChangeLog>
一些额外注意事项
- 确保你的Liquibase版本支持上述参数:
excludeData、diffTypes都是较新版本(3.0+)就支持的特性,建议使用稳定的最新版。 - 如果使用
diffExcludeObjects排除大表,注意格式必须是table:表名,多个表用逗号分隔,大小写要和数据库中的表名一致(部分数据库区分大小写)。 - 生成数据日志时,如果你的表有自增主键,Liquibase会自动处理
insert语句中的主键值,不用担心冲突。 - 完成后可以通过
liquibase:updateSQL目标预览执行语句,确认没有问题后再执行实际更新。
内容的提问来源于stack exchange,提问作者Luke Rogers
相关产品推荐
相关产品推荐

