如何处理以前有效的 Flyway 迁移变得无效
How to deal with previously valid Flyway migrations that became invalid
我有一个 Spring 启动应用程序,它使用 Flyway 在 Postgres 中进行数据库迁移。
它现在已经四岁了,所以我们正在谈论 Flyway 4.0.3、Spring Boot 1.3.x 和 Postgres 9.x。版本可能会升级,但我想在升级之前解决所有现有问题。
同时,Postgres 升级到高于 9.x。不幸的是,一些现有的迁移变得过时了,因为它们包含不推荐使用的语法。因此,现在使用新数据库(即在开发环境中)启动应用程序会导致这些迁移失败。在生产中它很好,因为这些迁移已经应用并且不会再次应用。
我很好奇解决此问题的最佳做法是什么。我不能直接修复现有迁移中的语法,因为这会导致生产环境中的校验和失败。我知道 repair
是一回事,但我不确定它是如何工作的以及如何将它与 Spring Boot.
一起使用
失败SQL:
UPDATE config
SET (description) = 'my description'
WHERE ...
正确SQL:
UPDATE config
SET description = 'my description'
WHERE ...
错误:
Message : ERROR: source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
编辑 24/04/2020 Spring 引导解决方案:
在 Grant Fitchey 在下面发布了关于如何使用 repair
的正确答案之后,我将添加我是如何使用 Spring Boot 来具体做到这一点的。我刚刚创建了一个 FlywayMigrationStrategy
的 bean,它调用
repair
在调用 migrate
之前:
@Bean
public FlywayMigrationStrategy cleanMigrateStrategy() {
return flyway -> {
flyway.repair();
flyway.migrate();
};
}
将此部署到生产环境时,在启动期间修复了 Postgres 中 schema_versions
table 中的校验和。在另一个版本中,我将再次删除 flyway.repair();
行,否则显然会产生应用无效迁移的风险。
您正在寻找修复选项。我不知道如何通过 spring 引导直接调用它,但是 documentation is here。这应该可以准确地满足您的需求。
因此,在这种情况下,第一步是修复迁移,以便它们在开发环境中正确执行。现在开发应该没问题,flyway应该迁移成功了。
在生产环境中,您现在应该会收到验证错误,因为校验和不同。 Flyway 修复将 'repair' 模式历史记录 table 以便它存储的校验和与磁盘上的新校验和匹配,因此 flyway 验证再次通过。
具体来说,flyway repair 正在做的是使模式历史记录 table 与您在磁盘上的内容相匹配。它将应用迁移的所有校验和更新为您在磁盘上的校验和(因此,只有在您确信更改相同时才使用它)。它还从 table 中删除所有失败的迁移条目(同样,只有在您自己清理数据库后才使用它)。
我有一个 Spring 启动应用程序,它使用 Flyway 在 Postgres 中进行数据库迁移。
它现在已经四岁了,所以我们正在谈论 Flyway 4.0.3、Spring Boot 1.3.x 和 Postgres 9.x。版本可能会升级,但我想在升级之前解决所有现有问题。
同时,Postgres 升级到高于 9.x。不幸的是,一些现有的迁移变得过时了,因为它们包含不推荐使用的语法。因此,现在使用新数据库(即在开发环境中)启动应用程序会导致这些迁移失败。在生产中它很好,因为这些迁移已经应用并且不会再次应用。
我很好奇解决此问题的最佳做法是什么。我不能直接修复现有迁移中的语法,因为这会导致生产环境中的校验和失败。我知道 repair
是一回事,但我不确定它是如何工作的以及如何将它与 Spring Boot.
失败SQL:
UPDATE config
SET (description) = 'my description'
WHERE ...
正确SQL:
UPDATE config
SET description = 'my description'
WHERE ...
错误:
Message : ERROR: source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
编辑 24/04/2020 Spring 引导解决方案:
在 Grant Fitchey 在下面发布了关于如何使用 repair
的正确答案之后,我将添加我是如何使用 Spring Boot 来具体做到这一点的。我刚刚创建了一个 FlywayMigrationStrategy
的 bean,它调用
repair
在调用 migrate
之前:
@Bean
public FlywayMigrationStrategy cleanMigrateStrategy() {
return flyway -> {
flyway.repair();
flyway.migrate();
};
}
将此部署到生产环境时,在启动期间修复了 Postgres 中 schema_versions
table 中的校验和。在另一个版本中,我将再次删除 flyway.repair();
行,否则显然会产生应用无效迁移的风险。
您正在寻找修复选项。我不知道如何通过 spring 引导直接调用它,但是 documentation is here。这应该可以准确地满足您的需求。
因此,在这种情况下,第一步是修复迁移,以便它们在开发环境中正确执行。现在开发应该没问题,flyway应该迁移成功了。
在生产环境中,您现在应该会收到验证错误,因为校验和不同。 Flyway 修复将 'repair' 模式历史记录 table 以便它存储的校验和与磁盘上的新校验和匹配,因此 flyway 验证再次通过。 具体来说,flyway repair 正在做的是使模式历史记录 table 与您在磁盘上的内容相匹配。它将应用迁移的所有校验和更新为您在磁盘上的校验和(因此,只有在您确信更改相同时才使用它)。它还从 table 中删除所有失败的迁移条目(同样,只有在您自己清理数据库后才使用它)。