一个模式中的Flyway多个元数据表

时间:2017-03-29 16:23:24

标签: postgresql flyway

我试图使用Flyway来模拟模块化应用程序的数据库。每个模块都有自己独立的表集,以及将控制该组表的版本控制的迁移脚本。

Flyway允许我为每个模块指定不同的元数据表 - 这样我就可以独立地对每个模块进行版本化。当我尝试升级应用程序时,我为每个模块运行一个迁移过程,每个模块都有自己的表和一组脚本。请注意,这些表都在同一模式中。

但是,当我尝试迁移我的应用程序时,第一次迁移是唯一有效的迁移。后续迁移失败,并出现以下异常:org.flywaydb.core.api.FlywayException: Found non-empty schema(s) "public" without metadata table! Use baseline() or set baselineOnMigrate to true to initialize the metadata table.

如果我手动为每个模块创建元数据表,则每个模块的迁移都能正常工作。自己创建表而不是让Flyway为我创建它似乎是一个解决问题的黑客,而不是解决方案本身。

这是一种独立管理多组表的有效方法,还是有更好的方法可以做到这一点?这是自己创建元数据表的有效方法吗?

2 个答案:

答案 0 :(得分:5)

理想的解决方案是将模块拆分为模式。这为每个模块提供了一个有效的隔离单元,也非常适合模块化应用程序(模块完全隔离和自我管理),而不是将所有内容都转储到单个模式(尤其是公共模式)中。例如

application_database
    ├── public
    ├── module_1
    │   ├── schema_version
    │   ├── m1_t1
    │   └── m1_t2
    ├── module_2
    │   ├── schema_version
    │   ├── m2_t1
    │   └── m2_t2
    ...

您的第二个选择是继续使用公共架构来托管所有表,但是为每个schema_version使用单独的架构。这不是重构努力,但肯定是比上面提到的更不优雅的设计。例如

application_database
    ├── public
    │   ├── m1_t1
    │   ├── m1_t2
    │   ├── m2_t1
    │   └── m2_t2
    ├── module_1
    │   └── schema_version
    │
    ├── module_2
    │   └── schema_version
    ...

答案 1 :(得分:1)

我认为您需要在执行迁移之前对每个模块进行基线处理。您需要传递table选项以覆盖每个模块的schema_version,例如flyway.table=schema_version_module1。正如错误消息所示,您也可以使用baselineOnMigrate,但在文档(https://flywaydb.org/documentation/commandline/migrate)中会发出警告。

我们正在考虑采用与另一个schema_version表类似的方法来应用和记录无法干净地推广到每个环境的数据修复。