【发布时间】:2015-04-29 13:08:35
【问题描述】:
Liquibase 已集成到我们的 Spring 应用程序中,并且在应用程序启动阶段执行数据库迁移。
通过 Maven 插件运行 DbDoc 时,所有更改都报告为“Pending Changes (NOT YET RAN)”。所以我无法为我们的下一个版本创建差异视图。
我发现的问题是 Spring bean 对 DATABASECHANGELOG 表中的更改日志条目使用类路径相对路径。通过 Maven 插件运行 DbDoc 时,使用相对于 Maven 项目根目录的文件路径。
NotRanChangeSetFilter 的代码无法处理这种差异: http://grepcode.com/file/repo1.maven.org/maven2/org.liquibase/liquibase-core/3.3.2/liquibase/changelog/filter/NotRanChangeSetFilter.java
尤其是下面的比较是行不通的:
ranChangeSet.getChangeLog().equalsIgnoreCase(changeSet.getFilePath())
这些方法返回以下值:
getChangeLog(): classpath:changelog/5.3.3/nos_add_acp_data.xml
getFilePath(): src/main/resources/changelog/5.3.3/nos_add_acp_data.xml
因此,equalsIgnoreCase 比较失败,这导致所有更改都被列为“Pending / NOT YET RAN”。
是否有任何已知的解决方法?我能想到的唯一解决方案是提供我们自己的 NotRanChangeSetFilter 实现,并在执行 Liquibase Maven 插件之前将其放在类路径中。是否有任何其他想法甚至官方解决此问题?
2015-04-30 更新: 经过大量调试,我认为 DATABASECHANGELOG 表中的路径必须在存储之前进行规范化。此外,每个工具还必须标准化其路径,以便比较工作。我在代码中发现了以下与当前概念比较失败的地方:
- RanChangeSetFilter.getRanChangeSet():equalsIgnoreCase() 比较
- ValidatingVisitor.visit():ranIndex.get(changeSet.toString(false));
- NotRanChangeSetFilter.accepts():equalsIgnoreCase() 比较
- RanChangeSet.isSame():equalsIgnoreCase() 比较
在后者中,有一个“normalize()”方法从路径中去除 classpath: 前缀。但这只是 4 个地方之一。
DbDoc 工具似乎能够使用相对于 Maven 项目根目录的源代码路径和类路径路径。所以在一个MAven项目中有如下配置选项:
<changeLogFile>changelog/complete.xml</changeLogFile> -> "classpath:" prefix is missing in the comparison
<changeLogFile>src/main/resources/changelog/complete.xml</changeLogFile> -> "src/main/resources" is the prefix in the comparisons
顺便说一句,第一个选项应该记录在 Maven 插件文档中。
拉取请求以使 DbDoc Maven 插件工作: https://github.com/liquibase/liquibase/pull/413
问候, 迈克尔
【问题讨论】:
标签: liquibase