在 flyway 中使用共享数据库脚本

Posted

技术标签:

【中文标题】在 flyway 中使用共享数据库脚本【英文标题】:Using shared database scripts in flyway 【发布时间】:2017-08-05 21:22:39 【问题描述】:

我有许多使用 Spring-Boot / Gradle 用 Groovy 编写的项目。所有这些应用程序都为不同的客户端执行类似的工作,但共享大量功能。

为了避免代码重复,我已将共享组件分离到一个库中,当然这对于 Groovy 代码来说效果很好。但是,该库还包含用于创建该库所依赖的架构的 Flyway 脚本。

由于数据隔离规则以及为了使应用程序完全独立,每个应用程序都需要在其自己的架构中拥有自己的数据库表副本,并且每个应用程序在其自己的 application.yaml 中都有自己的数据库连接详细信息.

然后我无法解决的是如何在单独的项目构建中使用共享的 Flyway 脚本。

我可以看到实现此目的的一种方法是每次针对适当的数据库运行库的 Flyway 迁移多次(每个应用程序一次),但这将涉及将所有应用程序的数据库详细信息放入库中 - 这是再次重复。

我可以看到实现此目的的另一种方法是将 Flyway 脚本放入应用程序项目中,但这将涉及从库中复制脚本,因此我将拥有 n 个副本,而不是拥有一个副本。这会使更改变得痛苦(如果我想将更改应用于所有或许多项目)并且还将应用程序与应该被库隐藏的数据库模式定义联系起来。

还有其他人处理过这个问题吗?我错过了什么明显的东西吗?还是我只是在询问 Flyway 做不到的事情?

谢谢

【问题讨论】:

我可能误读了,但是库不是它自己的 JAR,这样您就可以将其导入其他项目吗?然后,您将在每个应用程序中调用诸如 SchemaUtil.migrate() 之类的方法。 您还没有说这是单个多模块构建还是多个构建。如果单个多模块构建一个项目可以访问另一个项目的configurations。如果单独构建,您可能需要发布/使用包含 sql 文件的工件(jar) 【参考方案1】:

您的常用类文件和flyway 脚本是否在同一个.jar 文件中?如果这是真的,那么你不会想要你的 buildscript 类路径中的 jar,所以我建议将脚本提取到一个文件夹并从文件系统中查找。

例如:

buildscript 
    classpath 'my.db:driver:1.0'

apply plugin: 'groovy'
configurations 
    flywayScripts  traisitive = false 

dependencies 
    compile 'com.foo:common:1.0' // assuming you also want to compile against common classes
    flywayScripts 'com.foo:common:1.0'

task extractFlywayScripts(type: Copy) 
    from zipTree(configurations.flywayScripts.singleFile).matching 
        include 'path/to/migration/scripts/*.xml'
    
    into "$buildDir/flywayScripts"


// wire the extraction task into the DAG
flywayMigrate.dependsOn extractFlywayScripts

flyway 
    def yamlConfig = parseYaml('path/to/application.yaml') // TODO: implement parseYaml(...)
    locations = ["filesystem:$buildDir/flywayScripts", "filesystem:src/main/resources/db/migration"]
    url = yamlConfig.url
    user = yamlConfig.user
    password = yamlConfig.password

    // etc        

【讨论】:

我的 Flyway 脚本是 sql 脚本而不是 Java,所以它们不在 jar 中。这是一件好事吗?我想这将涉及更改库构建脚本以在 jar 中包含 sql 脚本 - 但这感觉不对(不是说这是错误的做法) 默认情况下,Gradle(和 Maven)会将 src/main/resources 中的所有内容打包到 jar 中。通常的做法是在 jar 中包含非 java 资源,包括 xml、sql、yaml、图像等。 我的常用类文件和 flyway 脚本现在在同一个 .jar 文件中。然后我使用了位置=“类路径:..../db”,这就像我希望的那样工作。阅读您的帖子,您提出了一种不同的方法,但我不太明白背后的原因......“您不希望在您的 buildscript 类路径中使用 jar”您能解释一下原因吗? 在 buildscript 类路径和编译类路径上放置类对我来说感觉很脏。我不确定是否会有类加载问题

以上是关于在 flyway 中使用共享数据库脚本的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flyway 在多个模式上运行 SQL 脚本

是否可以在 Spring Boot 应用程序中使用脚本创建数据库,并使用 flyway for postgres?如果是的话怎么办?

在 Bluehost 共享主机计划中,如何从 PHP 脚本创建数据库? [关闭]

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

如何使用flyway创建数据库?

最佳实践:使用后如何修改flyway迁移脚本