如何使用类路径回滚 Liquibase 的数据库更改

How to roll back a database change with Liquibase using classpath

我的应用程序使用 Liquibase 来管理数据库更改。它像这样设置 Liquibase:

@Bean(name = "liquibase")
public SpringLiquibase liquibaseData() {
    final SpringLiquibase liquibase = new SpringLiquibase();
    liquibase.setDataSource(dataSource);
    liquibase.setChangeLog("classpath:/db/changelog/db.changelog-master.xml");
    return liquibase;
}

它目前只有一个变更集。当 运行 应用程序应用变更集时,将按预期将记录插入 DATABASECHANGELOG,其中 FILENAMEclasspath:/db/changelog/0.0.1/db.changelog.xml

当我执行 liquibase rollbackCount 1 时,响应是 Liquibase Rollback Successful,但更改没有回滚。

手动回滚更改(删除由更改集创建的 table)后,我执行 liquibase update。更新成功,但是FILENAMEdb/changelog/0.0.1/db.changelog.xml。我执行 liquibase rollbackCount 1,更改按预期回滚。

这是我的 liquibase.properties:

driver: oracle.jdbc.driver.OracleDriver
classpath: ../../../../../client-ui/build/libs/client-ui.war
url: jdbc:oracle:thin:@localhost:1521/orcl
username: the-username
password: the-password
changeLogFile: classpath:/db/changelog/db.changelog-master.xml

问题的症结似乎在于 FILENAME 应用程序应用变更集与命令行应用变更集时不同。如何配置命令行参数,以便它创建一个 DATABASECHANGELOG 记录,其 FILENAME 与应用程序创建的记录相同?

是的,问题是 FILENAME 不同。 Spring 有时包括类路径:在它们的 URL 中,Liquibase 刚刚使用。 Liquibase 中有代码尝试处理 "sometimes there classpath:" 前缀,但听起来在回滚逻辑中没有正确处理。

在最近的版本中,类路径前缀的处理方式有了一些改进,您尝试过 Liquibase 3.4.0 吗?

否则,通过 spring 进行的 Liquibase 更新应该可以在有或没有类路径前缀的情况下正常工作,所以如果你修复了 FILENAME 字段,你应该是好的。如果您使用 mysql,则类似于 UPDATE DATABASECHANGELOG SET FILENAME = SUBSTR(FILENAME, 10) WHERE FILENAME LIKE 'classpath:%'。您可以将 runAlways=true changeSet 放在更改日志文件的底部,让它在每次更新时自动清理路径。