Closed1

SpringBootでflyway

misakamisaka

flywayを利用すると、マイグレーション管理を行えます

  • flyway_schema_history
    • 管理テーブル
    • 初期マイグレート時に作成される
    • 主にバージョン番号を管理している

依存の追加

implementation 'org.flywaydb:flyway-core'
// compileOnly 'org.flywaydb:flyway-core' こっちだと実行時に動きません

プロパティファイルを修正して
マイグレーションの有効設定をする

flyway:
    enable: true
    baseline-on-migrate: true # 既にあるテーブルなどがあるデータベースでもマイグレーションを実行する

flywayはテーブル設計を1から行うために作られているので、通常は何かしらのテーブルがある状態で行うとエラーになる。
そのため他に定義済のテーブルがあってもエラー無く進めるために設定する
参考

マイグレーションファイルの準備
書式

  • X-<Version>__<Description>.sql
    • X
      • V:デフォルト
      • R:リピータブルマイグレーション(マイグレーションファイルのチェックサムが変わるごとにマイグレーションが適用される)
    • <Version>
      • バージョン番号と説明はアンダーバーを2つ続けて区切る
    • <Description>
      • 説明の記載

resources/db/migrationフォルダに投入する
例:

  • R__1_create_tables.sql

  • R__2_insert_code.sql

  • R__3_insert_master.sql

  • 起動するとマイグレーションが実行される

  • 通常起動のたびにマイグレーションが実行されては困ってしまう

現状DBにテーブルがあるが、create対象のテーブルはない

V1__create_table.sql
V__2_insert_sample.sql

→ 普通に実行
public.flyway_schema_historyのみ作成された
versionは1

おそらくV2以降のものが実行されるとおもう
V1はそもそも予約的なものでflyway_schema_historyの作成を担っているのでは?

2回目

V1__
V2__

V1が実行されたない

Caused by: org.postgresql.util.PSQLException: ERROR: relation "samples" does not exist

既にversionが1なのでV1__がスキップされていた

V2__
V3__

にしたところ実行された
じゃあこれでバージョンが2になるの?というとそういうことではない

みたところバージョンが3まで進んでいるので、次回以降V4__からが対象になる

わかったこと

  • flyway_schema_historyのバージョンが1の時は、V1が実行されない
  • 同じバージョン番号を持ったファイル名、V1__ V1__だとエラーになる

もう一度挑戦

テーブルは空の状態で

V2__create
v3__insert

これが流れるか確認する

流れた。これなら問題ない

もう一度確認のため

V1__
V2__
でテーブル空で行う

やはりV1__がスキップされる

えらーになった

Caused by: org.flywaydb.core.internal.command.DbMigrate$FlywayMigrateException: Migration V2__insert_sample.sql failed
	

おそらくデフォルト

いかの設定がデフォルトで動いている可能性を感じる

baseline-version: 1

これは

flyway:
    enable: true
    baseline-on-migrate: true # 既にあるテーブルなどがあるデータベースでもマイグレーションを実行する

このbaseline-on-migrateがtrueの時に、baseline-versionまでの実行をスキップ(実際にはflyway_schema_historyのバージョンの登録値を設定している)してくれる

そのためversion: 2 を指定すれば V3__からが対象のファイルと認識される

確認のため、このversion: 0にして行う

V1__
V2__
はそのままだ

spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://192.168.11.13:5432/school
    username: kakine
    password: teitoku
  flyway:
    enable: true
    baseline-on-migrate: true # 既にあるデータベースでもマイグレーションを実行する
    baseline-version: 0	

結果

やはりそうだ
V1__もV2__も実行された

一見V1からファイルを始めるべきだろうと思っていても、実は思わぬ落とし穴があったわけです

ところでファイルの名にはVとRがまたはUなんかもあったか?
VはデフォルトのVだ。さてRはリピータブルマイグレーションという。マイグレーションファイルのチェックサムが変わるごとにマイグレーションが適応されるものだ

Rというのはバージョン番号で管理しない

チェックサムについて
https://wa3.i-3-i.info/word1240.html

まずこれだとR1__R2__が無視された。V1__V2__までの実行が確認できた

次にすべてRにして実行した

なんと何も作成されなかった

これはRがバージョン番号で管理しないため、ファイル名をR__hoge_fuga.sqlにする必要があるからだ。

V1__
V2__
R__3
R__4

今度はmasterテーブル含めて作成された。
そして管理テーブルではバージョンに番号が入ってないことも確認できた。

ではこの状態でファイルを変更して実行してみる

ファイルの変更があったためか実行された

今回はインサート文なので既存のレコード行に該当するレコードもインサートされた。

次にファイルの変更をせずに実行しよう
このときにインサートが行われていなければ、ファイルの変更時のみ反応していることがわかる

予想通り変わることはなかった

参考

https://kojion.com/posts/806

このスクラップは2022/09/26にクローズされました