Flyway による DB マイグレーション (Java)
[履歴] [最終更新] (2017/06/05 00:14:04)
最近の投稿
注目の記事

概要

Flyway は DB マイグレーションを実現するためのツールです。主に Java を対象としています。Rails におけるマイグレーション機能のようなものです。基本的な使い方をまとめます。

公式ドキュメント

インストール

Flyway は後述の Spring Boot プラグインJava API 等によってアプリケーションから利用することもできますが、ここではコマンドラインから単体で Flyway を利用する場合を考えます。コマンドラインから利用する方法は複数提供されていますが、特に以下の三つを対象とします。

flyway コマンド

こちらのページCommand-line Tool からコマンドをダウンロードして解凍します。

wget https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/4.2.0/flyway-commandline-4.2.0-linux-x64.tar.gz
tar zxvf flyway-commandline-4.2.0-linux-x64.tar.gz

Maven サブコマンド

こちらのページを参考に mvn コマンドをインストールします。以下のコマンドを実行してプロジェクトの雛形を生成します。

mvn archetype:generate -B \
  -DarchetypeGroupId=org.apache.maven.archetypes \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DarchetypeVersion=1.1 \
  -DgroupId=foo \
  -DartifactId=bar \
  -Dversion=1.0-SNAPSHOT \
  -Dpackage=foobar

pom.xml は以下のように設定します。

<project ...>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-maven-plugin</artifactId>
        <version>4.2.0</version>
        <configuration>
          <url>jdbc:mysql://localhost:3306/mydb</url>
          <user>root</user>
          <password></password>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>

Gradle タスク

こちらのページを参考に Gradle コマンドをインストールします。build.gradle は以下のように記載します。

buildscript {
    dependencies {
        classpath 'mysql:mysql-connector-java:6.0.6' // http://search.maven.org/#artifactdetails|mysql|mysql-connector-java|6.0.6|jar
    }
}

plugins {
    id "org.flywaydb.flyway" version "4.2.0"
}

flyway {
    url = 'jdbc:mysql://localhost:3306/mydb'
    user = 'root'
    password = ''
}

タスクが追加されたことを確認します。

$ ./gradlew tasks
...

Flyway tasks
------------
flywayBaseline - Baselines an existing database, excluding all migrations up to and including baselineVersion.
flywayClean - Drops all objects in the configured schemas.
flywayInfo - Prints the details and status information about all the migrations.
flywayMigrate - Migrates the schema to the latest version.
flywayRepair - Repairs the Flyway metadata table.
flywayValidate - Validate applied migrations against resolved ones (on the filesystem or classpath) to detect accidental changes that may prevent the schema(s) from being recreated exactly. Validation fails if differences in migration names, types or checksums are found, versions have been applied that aren"t resolved locally anymore or versions have been resolved that haven"t been applied yet

flyway コマンド

設定ファイルを編集します。

vi conf/flyway.conf

以下のようにログイン情報を設定します。ここでは MySQL への接続を考えます。

flyway.url=jdbc:mysql://localhost:3306/mydb
flyway.user=root
flyway.password=

こちらのページの情報をもとに、マイグレーション用の SQL を用意します。

touch sql/V1__Create_person_table.sql
vi sql/V1__Create_person_table.sql

V1__Create_person_table.sql というファイル名における「1」がマイグレーションバージョンです。Create_person_table がマイグレーションの説明です。

CREATE TABLE person (
    id INT NOT NULL,
    name VARCHAR(100) NOT NULL
);

事前に mydb を作成しておきます。

mysql> CREATE DATABASE mydb;

以下のコマンドでマイグレーションを実行します。

./flyway migrate

続けて以下のファイルを作成します。

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');

再度マイグレーションを実行します。

./flyway migrate

以下のような状態になります。

$ ./flyway info
Flyway 4.2.0 by Boxfuse

Database: jdbc:mysql://localhost:3306/mydb (MySQL 5.5)

+---------+---------------------+---------------------+---------+
| Version | Description         | Installed on        | State   |
+---------+---------------------+---------------------+---------+
| 1       | Create person table | 2017-04-04 19:43:42 | Success |
| 2       | Add people          | 2017-04-04 19:45:02 | Success |
+---------+---------------------+---------------------+---------+

$ mysql -uroot mydb -e 'SHOW TABLES';
+----------------+
| Tables_in_mydb |
+----------------+
| person         |
| schema_version |
+----------------+

$ mysql -uroot mydb -e 'SELECT * FROM schema_version'
+----------------+---------+---------------------+------+-----------------------------+-------------+--------------+---------------------+----------------+---------+
| installed_rank | version | description         | type | script                      | checksum    | installed_by | installed_on        | execution_time | success |
+----------------+---------+---------------------+------+-----------------------------+-------------+--------------+---------------------+----------------+---------+
|              1 | 1       | Create person table | SQL  | V1__Create_person_table.sql | -1455529326 | root         | 2017-04-04 19:43:42 |              2 |       1 |
|              2 | 2       | Add people          | SQL  | V2__Add_people.sql          | -1280448963 | root         | 2017-04-04 19:45:02 |              0 |       1 |
+----------------+---------+---------------------+------+-----------------------------+-------------+--------------+---------------------+----------------+---------+

その他のコマンドには以下のようなものがあります。

初期化 (危険)

DB Drop を実行して初期化します。Production 環境では絶対に実行してはいけないコマンドです。

./flyway clean

適用済マイグレーションファイルの検証

マイグレーションファイルに記載された情報が、DB に適用した時点から現在までに何らかの原因で書き換えられてしまっていないかどうかを検証します。

./flyway validate

Maven サブコマンド

マイグレーションファイルは src/main/resources/db/migration/ 内に設置します。

マイグレーション

mvn flyway:migrate

初期化 (危険)

mvn flyway:clean

状態の確認

mvn flyway:info

適用済マイグレーションファイルの検証

mvn flyway:validate

Gradle タスク

マイグレーションファイルは src/main/resources/db/migration/ 内に設置します。

マイグレーション

./gradlew flywayMigrate

初期化 (危険)

./gradlew flywayClean

状態の確認

./gradlew flywayInfo

適用済マイグレーションファイルの検証

./gradlew flywayValidate

Spring Boot 起動時に Flyway マイグレーションを実行 (補足)

こちらのページで環境構築の方法をまとめた Spring Boot から Flyway を利用することができます。アプリケーション起動時に DB マイグレーションが自動で実行されるようになります。

build.gradle

Flyway 公式ドキュメントに記載されているとおり、build.gradle に設定を追記します。

compile('org.flywaydb:flyway-core:4.2.0')

更に今回は MySQL を DB として利用するため、追加で以下の設定を行います。ちなみに、『Spring Batch サンプルコード』では、org.springframework.boot:spring-boot-starter-batchorg.springframework.boot:spring-boot-starter-jdbc に依存するため、明示的に設定する必要はありませんでした。

compile('org.springframework.boot:spring-boot-starter-jdbc')
compile('mysql:mysql-connector-java:6.0.6')

src/main/resources/application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: myuser
    password: myuser
    driver-class-name: com.mysql.jdbc.Driver

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

SQL ファイルの場所を変更したい場合flyway.locations を設定します。以下は既定の場所です。

DROP TABLE IF EXISTS people;
CREATE TABLE people (
    person_id BIGINT NOT NULL AUTO_INCREMENT,
    first_name VARCHAR(20),
    last_name VARCHAR(20),
    PRIMARY KEY (person_id)
);
関連ページ
    概要 こちらのページで環境構築した Spring Boot でバッチ処理アプリケーションを作成します。内部的に Spring Batch を利用します。CSV ファイルを読み込んで、文字列加工して、MySQL DB に出力するバッチ処理です。 公式ドキュメント Creating a Batch Service
    概要 こちらのページで使い方を把握した MyBatis を、こちらのページで使い方を把握した Spring Boot で利用するための基本的な設定およびサンプルコードをまとめます。サンプルコードにおいては、特に MySQL を対象とします。 MyBatis Spring-Boot-Starter チュートリアル