Flyway部分迁移遗留应用程序

时间:2017-03-27 12:59:40

标签: java database-migration flyway

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

这些迁移分为若干类别,例如用户管理的“帐户”和产品目录的“目录”。 文件名为$category.migration.$version.sql。此处,$category是上述类别之一,$version是从0 开始的整数版

e.g。 account.migration.23.sql

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

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

所以我做了以下事情:

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

代码

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();
}

因此会有元数据表catalog_schema_versionaccount_schema_version

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

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

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

1 个答案:

答案 0 :(得分:1)

最简单的解决方案是将schema_version表分别保存在另一个模式中。我回答了very similar question here

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