SpringBootで複数DBにFlywayのmigrationを実行する

2022/06/25に公開

SpringBootで複数DB構成でFlywayのmigrationを実行する方法です。

環境準備

まずDBを複数用意するためにDockerでpostgresを2つ起動します。

$ docker run -e POSTGRES_PASSWORD=password -p 5432:5432 postgres:14
$ docker run -e POSTGRES_PASSWORD=password -p 5433:5432 postgres:14

ソース

まず依存関係にflyway-coreを指定します。

build.gradle
dependencies {
	implementation 'org.flywaydb:flyway-core'
	runtimeOnly 'org.postgresql:postgresql:42.4.0'
}

続いてapplication.ymlの設定です。

application.yml
spring:
  datasource:
    first:
      jdbcUrl: jdbc:postgresql://localhost:5432/postgres
      username: postgres
      password: password
      driverClassName: org.postgresql.Driver
    second:
      jdbcUrl: jdbc:postgresql://localhost:5433/postgres
      username: postgres
      password: password
      driverClassName: org.postgresql.Driver
  flyway:
    enabled: true

次にMultiple Databasesを実現するためにDataSourceを設定します。

JdbcConfig.java
@Configuration
public class JdbcConfig {
  @Bean("firstDataSource")
  @ConfigurationProperties(prefix = "spring.datasource.first")
  public DataSource createFirstDataSource() {
    return DataSourceBuilder.create().build();
  }

  @Bean("secondDataSource")
  @ConfigurationProperties(prefix = "spring.datasource.second")
  public DataSource createSecondDataSource() {
    return DataSourceBuilder.create().build();
  }
}

これでMultiple Databasesは実現できました。
ここからFlywayの設定です。
DBが1つの場合だとresources配下のdb/migration 配下にsqlファイルを配置すれば起動しますが、今回は複数DBのためdb/migration 配下にフォルダを切ってそれぞれにsqlファイルを配置します。

こんな感じで配置しました。

src/main/resources/
├── db
│   └── migration
│       ├── first
│       │   ├── V1__create_table_users.sql
│       │   └── V2__insert_users.sql
│       └── second
│           ├── V1__create_table_books.sql
│           └── V2__insert_books.sql
└── application.yml

あとはFlywayの設定のみです。
FlywayクラスのBeanを作成し、メソッド内で対象ディレクトリの設定を行います。
FluentConfigurationではいくつかの設定ができますが、今回はsqlファイルの配置場所の指定だけを行うことします。

FlywayConfiguration.java
@Configuration
public class FlywayConfiguration {
  @Bean(name = "firstFlyway", initMethod = "migrate")
  public Flyway createFirstFlyway(@Qualifier("firstDataSource") DataSource dataSource) {
    return new Flyway(
        new FluentConfiguration().locations("db/migration/first").dataSource(dataSource));
  }

  @Bean(name = "secondFlyway", initMethod = "migrate")
  public Flyway createSecondFlyway(@Qualifier("secondDataSource") DataSource dataSource) {
    return new Flyway(
        new FluentConfiguration().locations("db/migration/second").dataSource(dataSource));
  }
}

起動してみる

2022-06-25 23:18:04.125  INFO 8950 --- [           main] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 8.5.13 by Redgate
2022-06-25 23:18:04.125  INFO 8950 --- [           main] o.f.c.internal.license.VersionPrinter    : See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#8.5.13
2022-06-25 23:18:04.125  INFO 8950 --- [           main] o.f.c.internal.license.VersionPrinter    : 
2022-06-25 23:18:04.133  INFO 8950 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-06-25 23:18:04.316  INFO 8950 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-06-25 23:18:04.336  INFO 8950 --- [           main] o.f.c.i.database.base.BaseDatabaseType   : Database: jdbc:postgresql://localhost:5433/postgres (PostgreSQL 14.4)
2022-06-25 23:18:04.376  INFO 8950 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 2 migrations (execution time 00:00.015s)
2022-06-25 23:18:04.398  INFO 8950 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table "public"."flyway_schema_history" ...
2022-06-25 23:18:04.453  INFO 8950 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema "public": << Empty Schema >>
2022-06-25 23:18:04.463  INFO 8950 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "public" to version "1 - create table books"
2022-06-25 23:18:04.502  INFO 8950 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "public" to version "2 - insert books"
2022-06-25 23:18:04.530  INFO 8950 --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 2 migrations to schema "public", now at version v2 (execution time 00:00.088s)
2022-06-25 23:18:04.555  INFO 8950 --- [           main] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 8.5.13 by Redgate
2022-06-25 23:18:04.556  INFO 8950 --- [           main] o.f.c.internal.license.VersionPrinter    : See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#8.5.13
2022-06-25 23:18:04.556  INFO 8950 --- [           main] o.f.c.internal.license.VersionPrinter    : 
2022-06-25 23:18:04.557  INFO 8950 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Starting...
2022-06-25 23:18:04.592  INFO 8950 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Start completed.
2022-06-25 23:18:04.596  INFO 8950 --- [           main] o.f.c.i.database.base.BaseDatabaseType   : Database: jdbc:postgresql://localhost:5432/postgres (PostgreSQL 14.4)
2022-06-25 23:18:04.616  INFO 8950 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 2 migrations (execution time 00:00.008s)
2022-06-25 23:18:04.642  INFO 8950 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table "public"."flyway_schema_history" ...
2022-06-25 23:18:04.680  INFO 8950 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema "public": << Empty Schema >>
2022-06-25 23:18:04.689  INFO 8950 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "public" to version "1 - create table users"
2022-06-25 23:18:04.736  INFO 8950 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "public" to version "2 - insert users"
2022-06-25 23:18:04.766  INFO 8950 --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 2 migrations to schema "public", now at version v2 (execution time 00:00.095s)

起動とmigrationできた!

参考

Discussion