Flyway:如何在不出现“FlywayException:验证失败”的情况下替换已弃用的 SpringJdbcMigration?

Posted

技术标签:

【中文标题】Flyway:如何在不出现“FlywayException:验证失败”的情况下替换已弃用的 SpringJdbcMigration?【英文标题】:Flyway: How to replace deprecated SpringJdbcMigration without getting "FlywayException: Validate failed"? 【发布时间】:2019-05-12 08:10:07 【问题描述】:

将springboot 2.0.3升级到2.1.1还带来了新的flyway版本:5.2.3代替了5.0.7。

在 5.2.3 中,SpringJdbcMigration 已弃用,将在 flyway 6 中删除。我主要使用 sql 脚本,但我在项目中也有一个 java 迁移类(有 4 个 sql 迁移,最后一个 4.2 是java 迁移 - 更改旧数据只是一些快速而肮脏的黑客攻击,我不再需要它了)。

所以我改变了那个类:

class V4_2__Update_foo implements SpringJdbcMigration 
    public void migrate(JdbcTemplate jdbcTemplate) throws Exception 
    ...
    

class V4_2__Update_foo extends BaseJavaMigration 
    public void migrate(Context context) throws Exception 
    JdbcTemplate jdbcTemplate = 
      new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), true));
    ......
    

这是唯一的变化,其他一切都一样。结果是

Application run failed
org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]:
Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException:
Validate failed: Migration type mismatch for migration version 4.2
....
Caused by: org.flywaydb.core.api.FlywayException:
Validate failed: Migration type mismatch for migration version 4.2
-> Applied to database : SPRING_JDBC
-> Resolved locally    : JDBC
at org.flywaydb.core.Flyway.doValidate(Flyway.java:1479)

我不想永久禁用验证,但我也不知道如何解决这个问题。我尝试使用谷歌搜索,但没有发现任何有关“类型不匹配”的信息。 在我的开发机器上,我尝试了“flyway repair”,但它只说

Repair of failed migration in Schema History table "PUBLIC"."schema_version" not necessary. No failed migration detected.
Successfully repaired schema history table "PUBLIC"."schema_version"

迁移 4.2 的类型在运行修复后仍然是“SPRING_JDBC”。 后来我完全删除了java类,这给了我一个警告

Schema "PUBLIC" has a version (4.2) that is newer than the latest available migration (4) !

但至少应用程序再次运行。不过,我不太愿意在生产中这样做。还有其他想法吗?

【问题讨论】:

【参考方案1】:

这绝对是一个错误。不幸的是,这不会在 5.2.x 中修复。 Flyway 6.0(将于 2019 年第一季度推出)将自动更正您的架构历史记录表并修复此问题。

或者,如果您真的不想等待,您可以手动查找架构历史记录表以消除此消息。

【讨论】:

我在使用 flyway 5.2.4 时也遇到过同样的情况。升级到 6.5.5 解决了这个问题。【参考方案2】:

问题:

[带有 SPRING_JDBC 的schema_version 表][1] [1]:https://i.stack.imgur.com/GI9So.png

解决方案: 我通过使用以下查询手动更新 schema_version 表来解决此问题:update schema_version set type='SQL', checksum=662979041 where script='V001_026__initial_reconciliation_config_env_NonProd.sql';

但是,要创建上述 UPDATE 语句,您将需要您之前使用 spring/java 类迁移的实际脚本的校验和,其中不包含校验和。

如何获得该校验和? 在您的本地,删除本地的 schema_version 表。成功启动您的应用程序,您现在应该创建了具有正确校验和并键入 SQL 的新 schema_version 表。

校验和是检查文件的完整性,即一旦得到校验和就不要修改文件。

然后在你的非生产环境中手动执行上面的 UPDATE 语句。

下一步,删除 java 类,将该脚本移动到 db/non-prod 等文件夹中,并在 application.yaml 中配置该文件夹

弹簧: 飞行路线: 位置:“类路径:db/migration,类路径:db/env/migration/V001/NON-PROD”

【讨论】:

以上是关于Flyway:如何在不出现“FlywayException:验证失败”的情况下替换已弃用的 SpringJdbcMigration?的主要内容,如果未能解决你的问题,请参考以下文章

我可以在不重新运行迁移的情况下修复 Flyway 中的版本号吗?

当不需要迁移时,如何让 flyway.cmd 使构建失败?

如何应对不断变化的 Flyway 迁移?

程序开发数据库版本控制必备 - Flyway

如何在 SQL Server 上的 Flyway 中禁用单个迁移的事务

如何将多个sql脚本执行到具有相同版本的flyway中