简体   繁体   English

带有 Gradle 的 Liquibase - changeLogFile 路径的愚蠢问题

[英]Liquibase with Gradle - silly problem with changeLogFile path

I'm stuck with a silly but annoying problem with implementing Liquibase to my existing project.在我现有的项目中实施 Liquibase 时,我遇到了一个愚蠢但烦人的问题。 After a lot of struggling I got it to work when starting the application, it runs through the master changelog and the included changelogs/changesets.经过大量的努力,我在启动应用程序时让它开始工作,它通过主变更日志和包含的变更日志/变更集运行。

The problem then occurred when I was adding the Luquibase Gradle plugin (which also is needed for future support) because the can't find the changelog file with the same path.当我添加 Luquibase Gradle 插件(未来支持也需要它)时,问题就出现了,因为找不到具有相同路径的更改日志文件。

When running the application through settings in application.yml file the changelog needs to be:通过 application.yml 文件中的设置运行应用程序时,更改日志需要是:

changeLog: classpath:/db/changelog-master.yml

to work (else the file can't be found) and the path in my changelog-master file is:工作(否则找不到文件)并且我的更改日志主文件中的路径是:

databaseChangeLog: - include: file: db/changelog/changelog.yml

But if I use plugin commands (changelogSync for example) the path needs to be from the src, like:但是,如果我使用插件命令(例如 changelogSync),则路径需要来自 src,例如:

src/main/resources/db/changelog-master.yml

for the plugin to find the changelog.让插件找到更新日志。

Would really appreciate some help to be able to use Liquibase both when starting the application and when using commands with the plugin but I can't seem to find a way around this silly thing.在启动应用程序时以及在使用插件命令时都能使用 Liquibase 时,我真的很感激一些帮助,但我似乎无法找到解决这个愚蠢事情的方法。

My activities in build.gradle is like this:我在build.gradle的活动是这样的:

liquibase {
activities {
    main {
        File propsFile = new File("${project.rootDir}/src/main/resources/liquibase.properties")
        Properties properties = new Properties()
        properties.load(new FileInputStream(propsFile))
        changeLogFile properties['changeLogFile']
        url properties['url']
        username properties['username']
        password properties['password'] 
     }
  }
}

And the Liquibase setup in application.yml is: application.yml 中的 Liquibase 设置是:

  spring:
   liquibase:
   enabled: true
   changeLog: classpath:/db/changelog-master.yml

There just must be an easy solution to this that I just can't seem to find?必须有一个我似乎找不到的简单解决方案吗? Feel free to ask for more code snippets but the rest is quite straightforward according to the documentation from Liquibase with the liquibase.propterties file etc in my setup.随意询问更多代码片段,但根据 Liquibase 的文档以及我的设置中的liquibase.propterties文件等,rest 非常简单。 I'm using Liquibase core v. 3.8.9 and plugin version 2.0.3.我使用的是 Liquibase 核心版本 3.8.9 和插件版本 2.0.3。
Thanks.谢谢。

I am not able to understand your question 100% but I think below solution will do the job for you to configure multiple class paths for liquibase我无法 100% 理解您的问题,但我认为以下解决方案将为您完成为 liquibase 配置多个 class 路径的工作

I think it'd be a good idea to make the following structure:我认为制作以下结构是个好主意:

--src
   -- main
     -- resources
       -- changelogs
          -- migrations1.xml
          -- migrations2.xml
          -- ...
          -- migrationsN.xml
       -- migrations.xml (it's a master changeLog which includes all the other changeLogs)

Try setting relative path to your child changeLog files as such:尝试将相对路径设置为您的子 changeLog 文件,如下所示:

<includeAll path="/changelogs" relativeToChangelogFile="true"/>

In the first link on includeAll docs there's a part about why it's not a very good practice to use itincludeAll文档的第一个链接中,有一部分是关于为什么使用它不是一个很好的做法

While the includeAll tag has many valuable uses, its use can cause problems down the road.尽管 includeAll 标签有许多有价值的用途,但它的使用可能会导致问题。 The biggest thing to avoid is to use the includeAll tag to simulate Ruby on Rails Active Migrations strategy of a list of changes, one per file, that are ran in file order.最大的避免是使用 includeAll 标签来模拟 Ruby on Rails Active Migrations 策略的更改列表,每个文件一个,按文件顺序运行。 While this seems like a good idea at first, it quickly runs into problems虽然一开始这似乎是个好主意,但很快就会遇到问题

If you do choose to use the includeAll tag, make sure you have a naming strategy in place that will insure that you will never have conflicts or need to rename files to change to force a reordering.如果您确实选择使用 includeAll 标记,请确保您有适当的命名策略,以确保您永远不会发生冲突或需要重命名文件以更改以强制重新排序。

so perhaps you may consider using <include> tag and list all the child changeLog files.所以也许您可以考虑使用<include>标记并列出所有子 changeLog 文件。

EG:例如:

<include path="changelogs/migrations1.xml" relativeToChangelogFile="true"/>
<include path="changelogs/migrations2.xml" relativeToChangelogFile="true"/>
...etc.

I can belatedly offer a workaround which I've found.我可以迟来提供我发现的解决方法。 I experienced a similar issues to what you described, which I've captured in detail in the Liquibase community .我遇到了与您描述的类似的问题,我已在Liquibase 社区中详细记录了这些问题。 I am using liquibase version 4.3.2 and Gradle plugin 2.0.3.我正在使用 liquibase 版本 4.3.2 和 Gradle 插件 2.0.3。

In my example, I was using a.xml master including mysql.sql files在我的示例中,我使用的是 a.xml 主控,包括 mysql.sql 文件

./src
└── main
    ├── java
    └── resources
        ├── application.properties
        └── db
            └── changelog
                ├── init
                │   ├── 1-0-table.mysql.sql
                │   └── 1-0-view.mysql.sql
                └── master.xml

master.xml

<?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.8.xsd">  

  <include  file="init/1-0-table.mysql.sql"
            relativeToChangelogFile="true" />

  <include  file="init/1-0-view.mysql.sql"
            relativeToChangelogFile="true"
            context="!test"/>

</databaseChangeLog>

After moving to a.yml master including.yml files, I have been able to run the updates without any conflict from the classpath prefix, even though the classpath prefix is only used in spring.移动到包含 .yml 文件的 .yml 主文件后,我能够运行更新而不会与类路径前缀发生任何冲突,即使类路径前缀仅用于 spring。

./src
└── main
    ├── java
    └── resources
        ├── application.properties
        └── db
            └── changelog
                ├── init
                │   ├── 1-0-table.yml
                │   └── 1-0-view.yml
                └── master.yml

master.yml

databaseChangeLog:
  - include:
      file: init/1-0-table.yml
      relativeToChangelogFile: true
  - include:
      file: init/1-0-view.yml
      relativeToChangelogFile: true
      context: "!test"

But if I use plugin commands (changelogSync for example) the path needs to be from the src, like:但是,如果我使用插件命令(例如 changelogSync),则路径需要来自 src,例如:

To resolve this issue, you can configure the classpath base directory in the Liquibase task that is run by Gradle.要解决此问题,您可以在 Gradle 运行的 Liquibase 任务中配置类路径基目录。

This will ensure that the relative paths match after stripping this base path:这将确保在剥离此基本路径后相对路径匹配:

/src/main/resources/ /src/主要/资源/ db/changelog/changelog.yml = db/changelog/changelog.yml db/changelog/changelog.yml = db/changelog/changelog.yml

Also it resolves your issue with migration duplicating after «explicit point out the changlogFile in "Build.Gradle"»它还解决了您在«明确指出“Build.Gradle”中的changlogFile»之后迁移复制的问题»

Full config should be something like below (for you case):完整配置应该如下所示(针对您的情况):

liquibase {
  activities {
    main {
        File propsFile = new File("${project.rootDir}/src/main/resources/liquibase.properties")
        Properties properties = new Properties()
        properties.load(new FileInputStream(propsFile))
        changeLogFile properties['changeLogFile']
        url properties['url']
        username properties['username']
        password properties['password']
        classpath "${projectDir}/src/main/resources"
     }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM