sohatach's blog

http://github.com/soha

FlywayでDBマイグレーション

FlywayとはDBマイグレーションフレームワークです。
DBマイグレーションというと少し難しく聞こえますが、
私は、「SQLの変更を差分SQLファイルとしてバージョン管理するしくみ」と理解しています。
最新の状態の全ての最終結果のSQLをまとめてバージョン管理するのではなく、
実際にDBに適用可能な状態の差分のSQLファイルとして管理します。
またSQLの「変更の差分」を管理するため、DBを以前の状態に戻したり、
既存のデータを残したまま、最新のスキーマに上げたりすることが手軽にできます。
Railsなどでも同様のしくみがありますが、それのJava版です。
(ただしFlywayには、まだバージョンダウングレードの機能はないとのこと。。。

使い方

使い方は、公式サイトの以下のページに乗っているものを見るととても簡単であることがわかります。
http://flywaydb.org/getstarted/firststeps/gradle.html
(注:以降Gradleコマンドはインストールされ、PATHが通ってる前提で記載します。)

build.gradleの作成

build.gradle(Mavenで言うところのpom.xmlファイル)に以下の記載をします。

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.h2database:h2:1.3.170'
classpath 'org.flywaydb:flyway-gradle-plugin:3.0'
}
}

apply plugin: 'flyway'
apply plugin: 'java'

flyway {
url = 'jdbc:h2:file:target/foobar'
user = 'sa'
}

ここでは、データベースにh2を使うため、h2のJDBCライブラリと
flywayのプラグインのライブラリを依存ライブラリとして定義しています。

最初のマイグレーションファイルの作成

Flywayは、src/main/resources/db/migrationにあるマイグレーションファイル(SQLファイル)を
順次適用するようです。

そのため、以下のようなSQLファイルを用意しておきます。
ファイル名の冒頭に「V1__」とついているのが特に重要です。
これがマイグレーションする際に適用される順番になります。

src/main/resources/db/migration/V1__Create_person_table.sql

create table PERSON (
ID int not null,
NAME varchar(100) not null
);

マイグレーション実行

gradle flywayMigrate -i

ここでデータベース(h2)上にPERSONというテーブルが作成されます。

2つ目のマイグレーションファイル

src/main/resources/db/migration/V2__Add_people.sql

insert into PERSON (ID, NAME) values (1, 'Axel');
insert into PERSON (ID, NAME) values (2, 'Mr. Foo');
insert into PERSON (ID, NAME) values (3, 'Ms. Bar');

マイグレーション実行

gradle flywayMigrate -i

ここでPERSONテーブルに3つレコードが登録されます。

ここまでが公式資料のgetstartedで記載しているところですが、
追加で以下のようなことも試してみます。

3つ目のマイグレーションファイル

ファイル名の命名ルールはバージョン番号以外は特に制限はないようですが、
何をするかわかりやすいファイル名にすると良いようです。
以下の例では、PERSONテーブルにEMAILカラムを追加しています。


src/main/resources/db/migration/V3__Add_email_to_person.sql

alter table PERSON add EMAIL varchar(100);

マイグレーション実行

gradle flywayMigrate -i

ここでPERSONテーブルにEMAILカラムが追加されます。
既存の3つのレコードもそのまま残ります。


Flywayは、他のフレームワークなどとの依存関係も少なく
SQLファイルの変更の管理の仕方を変えるだけなので、
DDLを手で書いているような開発をしている場合には、
適用しておいて損はないしくみだと思いました。