はじめに
データベースマイグレーションツールの一つであるFlywayを触ってみます。
業務で使用しているものの、私がやっていることはDBに変更があった際のマイグレーションファイルを作成する程度なので、改めて使用方法などを整理できればと思います。
なお、私の仕事上ではSpring boot
と併用していますが、今回はSpring
プロジェクトを作成するほどのことでもないので、コマンドライン上でのお試しとします。
Spring
との併用はそのうちやります・・。
マイグレーションとは
データベースの変更を記録することで、データベースの変更を容易にするためのもの・・と理解しています。
やってみる
Flywayも、他のツールに漏れず公式ドキュメントが充実しているので、そちらを参考に実施していきます。
インストール
先述したように、今回はコマンドツールを用いてFlyway
を利用していきます。
また、今回は学習用ですので、Community Edition(無料)をインストールします。
こちらから、適宜環境にあったものをダウンロードしましょう。
FlywayをPATHに通す
Flyway
をPATHに通します。私はfish
というシェルを使用しているため、~/.config/fish/config.fish
に以下の記述を追記しました。
set PATH /Users/ochiaisho/devTools/flyway-7.8.2 $PATH
zsh
や、bash
など、各自の環境に合わせてPATHを通すようにしましょう。
flyway.confの修正
データベース接続情報をconf/flyway.conf
に記述します。
私の場合は以下のようになります。
flyway.url=jdbc:mysql://localhost:3306/flyway flyway.user=root flyway.password=password
マイグレーションファイルの作成
実際にデータベースへ反映するためのマイグレーションファイルを作成します。
今回は、新しくUser
というテーブルを作成するDDLを追加します。
create table USER ( ID int not null, NAME varchar(100) not null );
ここまでで、準備はあらかた終了です。
flyway migrate
それでは実際にflyway migrate
を実行してみましょう。
$ flyway migrate
成功すると、以下のようなレスポンスとなります。
(バージョンやデータベース名などは適宜読み替えてください。)
Flyway Community Edition 7.8.2 by Redgate Database: jdbc:mysql://localhost:3306/flyway (MySQL 8.0) Successfully validated 1 migration (execution time 00:00.017s) Creating Schema History table `flyway`.`flyway_schema_history` ... Current version of schema `flyway`: << Empty Schema >> Migrating schema `flyway` to version "1 - create user" Successfully applied 1 migration to schema `flyway`, now at version v1 (execution time 00:00.040s)
成功すると、User
テーブルと、flyway_schema_history
というテーブルが作成されます。
mysql> show tables; +-----------------------+ | Tables_in_flyway | +-----------------------+ | flyway_schema_history | | USER | +-----------------------+ 2 rows in set (0.00 sec)
User
テーブルは自分で作成したテーブルなのでいいとして、flyway_schema_history
というテーブルはなんなのでしょうか?
ということで、もう少し続けます。
flyway_schema_historyとは
平たく言うと、flyway_schema_history
はテーブルのマイグレーション(変更)の記録を保持するテーブルとなります。
見てみる方が早いと思いますので、とりあえず作成されたテーブルの中身を調べてみることにしましょう。
mysql> select * from flyway_schema_history; +----------------+---------+-------------+------+---------------------+------------+--------------+---------------------+----------------+---------+ | installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success | +----------------+---------+-------------+------+---------------------+------------+--------------+---------------------+----------------+---------+ | 1 | 1 | create user | SQL | V1__create_user.sql | 1761476051 | root | 2021-05-09 14:48:27 | 10 | 1 | +----------------+---------+-------------+------+---------------------+------------+--------------+---------------------+----------------+---------+ 1 row in set (0.00 sec)
今回、User
というテーブルを作成した履歴が残っているのがわかるかと思います。
履歴が残るということを確認したいので、試しに別のテーブルを作成してみましょう。
マイグレーションファイルを追加する
今回も、テーブル追加のためのマイグレーションファイルを作成しようと思います。
sql
ディレクトリ配下に、V2__create_second_table.sql
というファイル名で、適当なテーブルを作成しようと思います。
create table SECOND_TABLE( ID int not null, );
ファイルが作成できたら、再度flyway migrate
を実行してみます。
$ flyway migrate
成功すると以下のようなメッセージが返ってきます。
Flyway Community Edition 7.8.2 by Redgate Database: jdbc:mysql://localhost:3306/flyway (MySQL 8.0) Successfully validated 2 migrations (execution time 00:00.018s) Current version of schema `flyway`: 1 Migrating schema `flyway` to version "2 - create second table" Successfully applied 1 migration to schema `flyway`, now at version v2 (execution time 00:00.050s)
この状態で再度データベースの状態を確認してみましょう。
mysql> show tables; +-----------------------+ | Tables_in_flyway | +-----------------------+ | flyway_schema_history | | SECOND_TABLE | | USER | +-----------------------+ 3 rows in set (0.00 sec)
show tables
で確認すると、SECOND_TABLE
が作成されていることがわかりますね。
次に、flyway_schema_history
の中身も確認してみましょう。
mysql> select * from flyway_schema_history; +----------------+---------+---------------------+------+-----------------------------+------------+--------------+---------------------+----------------+---------+ | installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success | +----------------+---------+---------------------+------+-----------------------------+------------+--------------+---------------------+----------------+---------+ | 1 | 1 | create user | SQL | V1__create_user.sql | 1761476051 | root | 2021-05-09 14:48:27 | 10 | 1 | | 2 | 2 | create second table | SQL | V2__create_second_table.sql | 942681622 | root | 2021-05-09 15:17:43 | 15 | 1 | +----------------+---------+---------------------+------+-----------------------------+------------+--------------+---------------------+----------------+---------+ 2 rows in set (0.00 sec)
レコードが追加されていますね。
このような形で、Flywayが実行したマイグレーションの履歴がどんどん積み重なっていくことになります。
おまけ
実はSECOND_TABLE
を追加しようとしたところ、sql syntax error
が発生したため、マイグレーションに失敗した、という事象が発生していました。
そこで、SQLを修正し、再度flyway migrate
を実行したところ、さらに別のエラーが発生・・ということも発生したんですね。つまり、
という流れです。この時のエラー解消方法を念のため記録しておこうと思います。
エラー内容
まずは実際のエラー内容から。
(なお、実際はsql syntax error
も出ていましたが、直接Flyway
とは関係ないので割愛しています。)
ERROR: Validate failed: Migrations have failed validation Detected failed migration to version 2 (create second table). Please remove any half-completed changes then run repair to fix the schema history. Need more flexibility with validation rules? Learn more: https://flywaydb.org/custom-validate-rules
Please remove any half-completed changes then run repair to fix the schema history.
ということなので、不完全な状態の変更を削除してから再実行するのが正しいようです。
ここで、上記の1.
でエラーが発生した直後のflyway_schema_history
を確認してみます。
+----------------+---------+---------------------+------+-----------------------------+------------+--------------+---------------------+----------------+---------+ | installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success | +----------------+---------+---------------------+------+-----------------------------+------------+--------------+---------------------+----------------+---------+ | 1 | 1 | create user | SQL | V1__create_user.sql | 1761476051 | root | 2021-05-09 14:48:27 | 10 | 1 | | 2 | 2 | create second table | SQL | V2__create_second_table.sql | -371576338 | root | 2021-05-09 15:15:48 | 17 | 0 | +----------------+---------+---------------------+------+-----------------------------+------------+--------------+---------------------+----------------+---------+
実は、マイグレーションに失敗しても、flyway_schema_history
にレコードは追加されます。
ここでさらにレコードの内容をみてみると、success
というカラムがマイグレーションの成否を表すカラムであることに気づくと思います。
1が成功、0が失敗ですね。
そこで、マイグレーションに失敗しているレコードであるsuccess=0
のレコードを削除してから再度flyway migrate
を実行することでエラーが解消され、マイグレーションが成功しました。
終わりに
マイグレーションツールを使用すれば、データベースに対する変更が正しい順序で反映されるので、ちゃんと使用できれば便利ですね。今回はやりませんでしたが、例えばカラムの削除・カラム定義の変更など、テーブルの初期状態からの変化を正しい順序で実行していくというのは手作業ではどうしても難しいシーンもあると思いますので、そういったことへの対策にもなりそうです。