将includeAll与classpath *一起使用时,变更集文件的Liquibase执行顺序: [英] Liquibase execution order of changeset files when using includeAll with classpath*:

查看:657
本文介绍了将includeAll与classpath *一起使用时,变更集文件的Liquibase执行顺序:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在春季环境(3.2.x)中使用liquibase(3.1.1),并通过inlcudeAll标记将更改集加载到主文件中.在那里,我使用"classpath *:/package/to/changesets"作为路径.

I am using liquibase (3.1.1) in a spring environment (3.2.x) and load the changesets via the inlcudeAll tag in a master file. There I use the "classpath*:/package/to/changesets" as path.

    <?xml version="1.0" encoding="UTF-8"?>
<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.1.xsd">

    <includeAll path="classpath*:/package/to/changesets"/>...

我使用诸如"nnn_changesetname.xml"之类的命名策略来保持排序.但是,当我查看变更集表时,不会保留通过文件名进行的排序.仅当变更集文件包含在目录中而不在类路径中时,这才起作用吗?

I use a naming strategy like "nnn_changesetname.xml" to keep ordering. But when I look into the changeset table this ordering via the filenames are not kept. Is this only working, if the changeset files are contained in a directory and not on the classpath?

更新

您好,我发现以下建议的解决方案还不够.我认为这取决于liquibase如何解析includAll属性的实现.就我而言,它首先解析所有文件夹",然后在每个文件夹中查找changeset xml.这将破坏所有classpath *:/changes位置中xml文件的顺序,因为现在在不同位置有多个"changes"文件夹.在这种情况下,我怀疑是虚拟"类路径文件夹的所有内容的合并,并在一个枚举中加载了所有资源.或者,我们可以允许inlcudeAll标签中的一些资源模式(例如resources ="classpath *:/changes/*.xml")直接选择所有需要的文件(使用path属性对其进行了尝试,但是没有用,因为它会检查是否存在文件夹)?

Hi, I found out that the below suggested solution is not enough. I think it lies in the implementation how liquibase resolves the includAll attribute. In my case it first resolves all "folders" and then looks into each folder for changeset xmls. This will break the ordering of the xml files in all classpath*:/changes locations, because there are now several "changes" folders in different locations. What I would suspect in such a case is a merge of all contents of this "virtual" classpath folders and loading of all resources in one enumeration. Or we could allow some resouce pattern in the inlcudeAll tag like resources="classpath*:/changes/*.xml" to directly select all needed files (tried it out with the path attribute, but did not work, because it checks for a folder)?

更新

我做了一个黑客检查返回枚举中的顺序是否从下面用anwser保留.为了达到这个目的,我检查了给定的程序包名称,如果它与我的模式匹配,我在其中添加了一个额外的"* .xml".使用此扩展程序,我可以根据需要获取所有变更集.

I made a hack to check if the ordering in the returned enumeration is preserved with the anwser from below. To achive this I checked for the given package name and if it matches my pattern I added an additional "*.xml" to it. With this extension I get all changeset as needed.

@Override
public Enumeration<URL> getResources(String packageName)
  throws IOException {
  if(packageName.equals("classpath*:/plugin/liquibase/changes/")) {
    packageName = packageName + "*.xml";
  }
  List<URL> resources = Collections.list(super.getResources(packageName));
  Collections.sort(resources, new Comparator<URL>() {

    @Override
    public int compare(URL url1, URL url2) {
      String path1 = FilenameUtils.getName(url1.getPath());
      String path2 = FilenameUtils.getName(url2.getPath());
      return String.CASE_INSENSITIVE_ORDER.compare(path1, path2);
    }

  });
  logger.info("Found resources: {}", resources);
  return Collections.enumeration(resources);
}};

在日志中,我现在可以看到资源具有正确的顺序.但是,当我查看表DATABASECHANGELOCK时,它不能反映枚举中的顺序.因此,似乎该值在其他地方已被重新引用.

In the log I can see now that the resources have the correct order. But when I look into the table DATABASECHANGELOCK it does not reflect the order I had in the enumeration. So it seems that this values get reodered somewhere else.

更新

进一步分析了代码,发现类 liquibase.parser.core.xml.XMLChangeLogSAXHandler 对返回的枚举进行了重新排序.因此,我的更改将无效.我不认为我也可以参加此类课程.

Analyzed the code furhter and found out that the class liquibase.parser.core.xml.XMLChangeLogSAXHandler makes a reordering of the returned enumeration. So my changes will have no effect. I do not think that I can hack into this class as well.

推荐答案

您是正确的,Liquibase依赖底层的列表文件"逻辑,该逻辑通过文件系统按字母顺序对文件进行排序,但显然不是通过类路径.

You are right, Liquibase is relying on the underlying "list files" logic which orders files alphabetically through the file system but apparently does not through classpaths.

我创建了 https://liquibase.jira.com/browse/CORE-1843跟踪修复程序.

I created https://liquibase.jira.com/browse/CORE-1843 to track the fix.

现在,如果您为spring配置liquibase.integration.spring.SpringLiquibase的子类,该子类使用对返回的枚举进行排序的方法覆盖getResources(String packageName),则该枚举应为您解决问题.

For now, if you configure spring with a subclass of liquibase.integration.spring.SpringLiquibase that overrides getResources(String packageName) with a method that sorts the returned Enumeration that should resolve the problem for you.

这篇关于将includeAll与classpath *一起使用时,变更集文件的Liquibase执行顺序:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆