複数のスキーマがあるDBに対して、Flyway+Springでアクセスしようとしたときに半日くらい設定に苦労したので、メモとして残しておきます。
環境
- Flyway
- 5.2.4
- PostgreSQL
- 13
- SpringBoot
- 2.3.5.RELEASE
- Java
- Java 11
- YAML
設定方法
spring: datasource: driver-class-name: org.postgresql.Driver url: jdbc:postgresql://localhost:5432/postgres username: root password: root flyway: schemas: public
何も設定しなかった時の挙動はどうなるか
DatabaseConnectionのDefaultのスキーマに接続します。ですので、PostgreSQLの場合は、DBに設定されたsearch_pathを元に接続スキーマを確認します。
公式引用。
# Comma-separated list of schemas managed by Flyway. These schema names are case-sensitive. If not specified, Flyway uses # the default schema for the database connection. If <i>flyway.defaultSchema</i> is not specified, then the first of # this list also acts as default schema. # Consequences: # - Flyway will automatically attempt to create all these schemas, unless they already exist. # - The schemas will be cleaned in the order of this list. # - If Flyway created them, the schemas themselves will be dropped when cleaning. # flyway.schemas=
Flyway公式の設定ファイルのURL。 flywaydb.org
PostgreSQLにて、search_pathを調べるSQL。
show search_path;
そもそもなぜ時間かかったか
spring.datasourceでスキーマを定義しようとしたため。
SpringではDBへの接続情報はdatasource内に記載するので、Flywayだろうとdatasource内に定義しようとしていました。その結果、PostgreSQL固有のスキーマ指定方法を探す等で遠回りしてしまいました。過去にFlywayを使用せずに、PostgreSQLでのスキーマ指定をして起動する方法を知っていたというところも混乱ポイントです。
また、Dockerで確認がうまくいっていたので、別部署にて払い出されたUserの権限やPassWordが誤っているという方向で調べてしまいました。
ちなみに、Flywayを使わずにPostgreSQLでスキーマを指定する場合、次のようにURLにスキーマを付与すると接続できます。
spring: datasource: driver-class-name: org.postgresql.Driver url: jdbc:postgresql://localhost:5432/postgres?currentSchema=test username: root password: root
教訓
実際の接続先のDBがOracleやMySQL、PostgreSQLであろうと、Flywayを通じてアクセスする以上はFlyway側に設定をする必要がある。
おそらくこの件に限らず、ライブラリを介在して処理をする場合はライブラリ側の設定を正とする必要がある。
ソースコード
終わりに
問題の切り分けがうまくできないと、無駄に時間を掛けてしまいますね…。今回の問題に限らずですが。
サクっと切り分けられるようになりたいです。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
参考
- データベースの初期化 spring.pleiades.io