仕事ではDBマイグレーションとしてFlywayを使用しています。ただ、表やテーブル等のDDLのみで、マスタデータ等のDMLは手動で管理していました。ですので、FlywayでDMLも管理することにしました。
しかし、そのまま適応してしまうと検証環境と本番環境のデータが同一になってしまい、結局差分は手動で投入する必要があります。
そこで、Flywayのオプションを駆使し、検証環境と本番環境で投入するデータを変更する方法を調べました。
設定方法
- SpringBootで環境ごとに読み込むプロファイルを変更できるようにする
※ このやり方はデフォルトではできないので、類似記事を読んでください。
# 検証環境用 ./gradlew bootRun -Pprofiles=local # 本番環境用 ./gradlew bootRun -Pprofiles=prd
- 検証環境に投入するデータと商用環境に投入するデータを用意し、別ディレクトリにする
/src/main/resources/db/migration # デフォルト /src/main/resources/db/dev # 検証環境用
- spring.flyway.locationsに読み込むクラスパスを指定する
検証環境用プロファイル。
spring: flyway: locations: classpath:db/migration,db/dev
本番環境用プロファイル。
spring: flyway: locations: classpath:db/migration # デフォルトなので設定不要でもOK
私の考えるよい管理方法
- 商用環境用データ
- V__を使用して、厳密にバージョン管理
- Insert
- 検証環境用データ
- R__を使用して、緩くバージョン管理
- Update
DEL-INSは管理が楽になりますが、DBセッションの管理をちゃんとしていないとファントムリードしてしまう恐れがあります。特にKubernetesを使用している場合は、アプリケーション起動タイミングでデータが入れ替わることになるため、入れ替わるタイミングが読めなくなります。そのアプリケーションの起動 = KubernetesのPodの入れ替わりを意識しなくていいというのは、もちろん通常ではいいことなんですが…。
# 商用環境用にInsert INSERT INTO BOOK values (1234567890123, 3);
# 検証環境用にUpdate UPDATE BOOK SET amount= 100 Where isbn = '1234567890123';
ソースコード
終わりに
マスタデータの投入は常に手動で行っていたので、Flywayで管理するという考えがありませんでした。マスタデータも管理すると、テスト実行するたびに読み込まれて実行時間が長くなることを恐れていました。
手動管理でデータの整合性を信じられなくなるデメリットの方が大きくなり、現在はこのように管理しています。
ただ、管理バージョンが増えれば増えるほど、実行時間が長くなることも事実です。定期的にマスタデータもリセットしつつ、正しく管理する方法も調べたいです。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
類似記事
gradleでのbootRun時にプロファイルを指定できるようにする nainaistar.hatenablog.com
参考
SpringBoot公式:79. データベースの初期化 spring.pleiades.io