如何使用Spring配置文件设置Flyway迁移文件的位置

8
我有两个Spring配置文件,分别是devtest,用于开发和测试环境。在每个环境中,我使用不同的数据库,即在dev中使用h2,而在testing中使用postgresql。以下是每个配置文件的属性文件,其中{vendor}由spring boot解析为相应的h2postgresql

application-dev.properties

spring.flyway.locations=classpath:db/migration/{vendor}

application-test.properties

#Data source
spring.datasource.url=jdbc:postgresql://localhost:5432/test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

#Flyway
spring.flyway.check-location=false
spring.flyway.locations=classpath:/db/migration/test/{vendor}

针对dev配置文件的Flyway迁移文件位于test/resources目录下,而针对test配置文件的迁移文件位于main/resources目录下。

enter image description here

enter image description here

当我使用test配置文件运行我的应用程序时,它只会在main/resources下选择迁移文件,这个功能正常。然而,当我使用dev配置文件运行我的单元测试时,我希望它只会在src/test/resources/db/migration/h2下选择文件。但是Flyway选取了来自main/resourcestest/resources的迁移文件,导致错误。

org.flywaydb.core.api.FlywayException: 找到多个版本为1的迁移

我不理解这种行为。有什么建议可以修复这个问题吗?
2个回答

14

好的,这就是我是如何做到的。

要求:

  1. 使用Spring profiles为不同的环境配置应用程序,包括 devtestprod 环境。
  2. 使用Spring profiles根据环境加载flyway迁移文件。

每个环境的数据库:

  1. H2 数据库适用于 dev 环境。
  2. postgresql 数据库适用于 test 环境。
  3. postgresql 数据库适用于 prod 环境。

配置:

  1. pom.xml 中创建Spring profiles devtestprod

    <profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <profile> <id>test</id> </profile> <profile> <id>prod</id> </profile> </profiles>

  2. 为每个profile创建属性文件

application-dev.properties

spring.flyway.locations=classpath:db/migration/{vendor}

由于在类路径中存在H2驱动程序时,Spring Boot将配置H2数据库。我们无需显式配置它。

application-test.properties

spring.datasource.url=jdbc:postgresql://localhost:5432/db_test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

spring.flyway.locations=/db/{vendor}/common,/db/{vendor}/test

应用程序生产环境配置文件

spring.datasource.url=jdbc:postgresql://localhost:5432/db_prod
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

spring.flyway.locations=/db/{vendor}/common,/db/{vendor}/prod
  1. Flyway迁移文件位置。

如果您注意到,我没有在src/main/resources下使用db/migration来放置迁移文件,这是默认位置。原因很简单,Flyway会选择此位置下的所有文件,这会导致不同环境下文件版本之间的冲突。例如,V2__data_insertion.sql存在于所有三个环境中,如果将它们嵌套在db/migration下,它将无法正常工作。 由于H2迁移文件属于默认配置文件,我已经将它们留在默认的Flyway迁移文件位置。

enter image description here

enter image description here

希望对您有所帮助!!!


0

这不仅仅是关于Flyway的问题。

Maven在构建期间有两个不同的类路径:

  1. 编译类路径 - 用于编译(包括src/main/*
  2. 测试类路径 - 实际上包括src/test/*(显而易见)和src/main/*,因为在测试中应该编译时间访问实际代码。

这就是为什么在运行时有两个有效的位置,而Flyway会找到多个迁移的原因。

另一个观察结果:

您的生产代码通常不应包含任何与测试相关的内容。但我看到您添加了:src/main/resources/application-test.properties 这个文件将出现在错误的生产产品中。

作为解决方法,您可以使用src/main/resources/application-prod.properties来定义实际迁移的位置“X”,而不是使用src/test/resources/application-test.properties来定义测试迁移的位置“Y”。使用Profile Test运行集成测试,您就找不到生产迁移了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接