无法从生成的差异变更日志更新

Can't update from a generated diff changelog

首先,我在 Node.

中使用一个名为 liquibase 的 npm 库到 运行 Liquibase

所以,我正在尝试使用 diffChangeLog 来比较两个数据库并生成它们差异的变更日志。通常会生成变更日志,但是当我尝试 运行 时,update 使用生成的变更日志 Liquibase 响应验证错误。这是输出:

node_modules/liquibase/lib/liquibase-4.0.0/liquibase --changeLogFile=examples/common/migration.xml --url="jdbc:mysql://127.0.0.1:3306/mySchema?useJvmCharsetConverters=true" --username=migration --password=migration --classpath=lib/migrator/drivers/mysql-connector-java-8.0.22.jar --changeLogFile=examples/DatabaseDiff/diffChangeLog.xml update 

Liquibase Community 4.0.0-beta1 by Datical
    Starting Liquibase at 17:54:32 (version 4.0.0-beta1 #6 built at 2020-04-20 18:23+0000)
    Unexpected error running Liquibase: Validation Failed:
         16 changes have validation failures
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-1::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-2::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-3::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-4::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-5::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-6::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-7::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-8::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-9::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-10::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-11::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-12::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-13::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-14::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-15::joao (generated)
              columns is empty, examples/DatabaseDiff/diffChangeLog.xml::1618001652047-16::joao (generated)

For more information, please use the --logLevel flag

这里是输出中提到的更新日志的一部分:

<changeSet author="joao (generated)" id="1618001652047-2">
    <createTable tableName="FeaturedProducer"/>
</changeSet>
<changeSet author="joao (generated)" id="1618001652047-3">
    <createTable tableName="PreVerification"/>
</changeSet>
<changeSet author="joao (generated)" id="1618001652047-4">
    <createTable tableName="Producer"/>
</changeSet>

我还尝试使用 SQL 格式生成更新日志(名为 changeLog.mysql.sql),但它创建了一个错误的 SQL 语法,例如:

CREATE TABLE USER ();

这引发了 MySQL 的语法错误。没错,我已经尝试 运行 手动执行此查询,但错误是一样的。

我猜 Liquibase 不允许我创建空列,但为什么呢? 我不明白发生了什么,Google 上的结果也不多。 谁能帮帮我?!

嗯,过了一会儿我们发现了问题。

为了调试这个问题,我用 Docker 提出了两个本地数据库并尝试了相同的操作,它工作得很好。

因此,我们想到出现此错误的原因可能是由于用户权限。我看到有人在谈论它,当用户没有足够的权限时,Liquibase 会吐出异常错误。

所以我为我的用户授予了该架构的所有权限并且它起作用了!实际上,我们只是又犯了一个错误,但绝对是进步!

错误是这样的:

liquibase.exception.LiquibaseException: liquibase.command.CommandExecutionException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
        at liquibase.integration.commandline.CommandLineUtils.doDiffToChangeLog(CommandLineUtils.java:250)
        at liquibase.integration.commandline.Main.doMigration(Main.java:1285)
        at liquibase.integration.commandline.Main.lambda$run[=10=](Main.java:314)
        at liquibase.Scope.lambda$child[=10=](Scope.java:149)
        at liquibase.Scope.child(Scope.java:160)
        at liquibase.Scope.child(Scope.java:148)
        at liquibase.Scope.child(Scope.java:127)
        at liquibase.Scope.child(Scope.java:173)
        at liquibase.Scope.child(Scope.java:177)
        at liquibase.integration.commandline.Main.run(Main.java:313)
        at liquibase.integration.commandline.Main.run(Main.java:169)
        at liquibase.Scope.child(Scope.java:160)
        at liquibase.Scope.child(Scope.java:134)
        at liquibase.integration.commandline.Main.run(Main.java:169)
        at liquibase.integration.commandline.Main.main(Main.java:148)
Caused by: liquibase.command.CommandExecutionException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
        at liquibase.command.AbstractCommand.execute(AbstractCommand.java:24)
        at liquibase.integration.commandline.CommandLineUtils.doDiffToChangeLog(CommandLineUtils.java:248)
        ... 14 more
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
        at liquibase.diff.output.changelog.DiffToChangeLog.print(DiffToChangeLog.java:193)
        at liquibase.diff.output.changelog.DiffToChangeLog.print(DiffToChangeLog.java:86)
        at liquibase.command.core.DiffToChangeLogCommand.run(DiffToChangeLogCommand.java:63)
        at liquibase.command.AbstractCommand.execute(AbstractCommand.java:19)
        ... 15 more
Caused by: java.lang.RuntimeException: java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
        at liquibase.diff.output.changelog.DiffToChangeLog.run(DiffToChangeLog.java:176)
        at liquibase.Scope.lambda$child[=10=](Scope.java:149)
        at liquibase.Scope.child(Scope.java:160)
        at liquibase.Scope.child(Scope.java:148)
        at liquibase.Scope.child(Scope.java:127)
        at liquibase.diff.output.changelog.DiffToChangeLog.print(DiffToChangeLog.java:119)
        ... 18 more
Caused by: java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
        at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
        at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
        at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
        at java.base/java.util.Objects.checkIndex(Objects.java:372)
        at java.base/java.util.ArrayList.get(ArrayList.java:459)
        at liquibase.change.ColumnConfig.<init>(ColumnConfig.java:154)
        at liquibase.change.AddColumnConfig.<init>(AddColumnConfig.java:16)
        at liquibase.diff.output.changelog.core.MissingIndexChangeGenerator.fixMissing(MissingIndexChangeGenerator.java:70)
        at liquibase.diff.output.changelog.ChangeGeneratorChain.fixMissing(ChangeGeneratorChain.java:48)
        at liquibase.diff.output.changelog.ChangeGeneratorFactory.fixMissing(ChangeGeneratorFactory.java:95)
        at liquibase.diff.output.changelog.DiffToChangeLog.generateChangeSets(DiffToChangeLog.java:279)
        at liquibase.diff.output.changelog.DiffToChangeLog.printNew(DiffToChangeLog.java:203)
        at liquibase.diff.output.changelog.DiffToChangeLog.run(DiffToChangeLog.java:125)
        ... 23 more

顺便说一下,日志记录真的很糟糕...

MissingIndexChangeGenerator.fixMissing(MissingIndexChangeGenerator.java:70) 部分引起了我的注意。在网上冲浪我几乎找不到任何东西,所以我们想:让我们检查一下那行的源代码。在他们的 GitHub 上,我们找到了异常的确切行,一切都变得更清楚了。

该错误意味着 Liquibase 无法检索某些 table 索引。 查看我们的数据库,我们被提醒一些索引实际上是另一个模式上 tables 的外键。我们使用的用户没有其他模式的权限。我们也为用户授予了第二个模式的所有权限,BAM,它终于成功了!

这里的教训是:Liquibase 的日志记录非常糟糕...哦,还有,永不放弃!