遗留应用的 Flyway 部分迁移

Flyway partial migration of legacy application

在我们想要用 Flyway 替换的自定义数据库迁移器的应用程序中。

这些迁移分为一些类别,例如用于用户管理的 "account" 和用于产品目录的 "catalog"。 文件名为 $category.migration.$version.sql。这里,$category是上述类别之一,$version是从0开始的整数版本

例如account.migration.23.sql

虽然有人可能会争辩说每个类别都应该是一个单独的数据库,但实际上并非如此,需要进行重大重构才能改变这一点。

我也可以为每个类别使用一个模式,但这同样需要重写所有 SQL 查询。

所以我做了以下事情:

  • $category.migration.$version.sql 移动到 /sql/$category/V$version__$category.sql(例如 account.migration.1.sql 变为 /sql/account/V1_account.sql
  • 每个类别使用元数据table
  • 将基准版本设置为零

在代码中

String[] _categories = new String[] { "catalog", "account" };
for (String _category : _categories) {
  Flyway _flyway = new Flyway();
  _flyway.setDataSource(databaseUrl.getUrl(), databaseUrl.getUser(), databaseUrl.getPassword());
  _flyway.setBaselineVersion(MigrationVersion.fromVersion("0"));
  _flyway.setLocations("classpath:/sql/" + applicationName);
  _flyway.setTarget(MigrationVersion.fromVersion(_version + ""));

  _flyway.setTable(category + "_schema_version");
  _flyway.setBaselineOnMigrate(true); // (1)
  _flyway.migrate();
}

所以会有元数据 tables catalog_schema_versionaccount_schema_version.

现问题如下: 从一个空数据库开始,我想按类别应用所有预先存在的迁移,如上所述。 如果我删除 _flyway.setBaselineOnMigrate(true); (1),那么 catalog 迁移(第一个)会成功,但它会抱怨 account 模式 public 不为空。

同样设置 _flyway.setBaselineOnMigrate(true); 会导致以下行为: "catalog" 的迁移成功但 V0_account.sql 被忽略并且 Flyway 以 V1_account.sql 开头,可能是因为它仍然以某种方式认为数据库已经基线化?

有没有人有解决问题的建议?

最简单的解决方案是将 schema_version 表分别保存在另一个架构中。我已经回答了 .

根据您对 baseline 的观察,这些是预期的特征。 account 的迁移从 v1 开始,因为结合了 baseline=0baselineOnMigrate=true 和非空目标模式(因为 catalog 已经填充了它)Flyway 有确定这是一个等于基线的预先存在的数据库 - 因此从 v1.

开始