DBマイグレーションツール FlyWay の使い方(Gradle Plugin)

参考サイト:FlyWay公式

Gradle Pluginの定義追加

FlyWayを使用したいプロジェクトの build.gradle に以下の設定を記述する。

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        // 使用するDBのJDBCドライバをクラスパスに設定する
        classpath "com.microsoft.sqlserver:mssql-jdbc:${sqlserver_version}"
    }
}

plugins {
  id 'org.flywaydb.flyway' version "${flyway_version}"
}

// パラメーターはここに随時追加していく
flyway {
    // DBの接続先情報を設定(環境変数から取得)
    driver = 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
    url = "$System.env.DATASOURCE_URL"
    user = "$System.env.DATASOURCE_USER_NAME"
    password = "$System.env.DATASOURCE_PASSWORD"
    schemas = ["$System.env.DATASOURCE_SCHEMA_NAME"]
}

依存関係のバージョンは gradle.properties に記述する。

# JDBC Driver(SQL Server)
sqlserver_version = 9.2.1.jre11
# FlyWay
flyway_version=7.15.0

マイグレーションSQLを作成する

デフォルトではsrc/main/resources/db/migrationに置かれたSQLファイルがマイグレーションの対象となる。
ファイル名は以下の書式となるようにする。

V<Version>__<Description>.sql

項目 説明
V 大文字のV。SQLファイルの頭文字に必ずつける。
パラメーター「sqlMigrationPrefix」で変更可能。
V
<Version> 一意なバージョン番号。半角数値と、ドット(.)またはアンダーバー(_)の組み合わせで指定する。
アンダーバーは、実行時にドットに変換される。
2.1.0
3_1_2
2021.10.01
__ アンダーバー2つ。「バージョン番号」と「説明」とを区切る。
パラメーター「sqlMigrationSeparator」で変更可能。
__
<Description> 説明。そのバージョンの説明を記述する。flyway info コマンドを実行した時に Description として出力される。日本語も記述できるが、日本語が記述されたファイルではflyway infoの表示結果がずれる。
説明内に記述したアンダーバーは実行時に空白スペースに置き換わる。
insert_data
create_table

上記の項目を埋め込んだ、ファイル名の例は以下の通り。

  • V1.0__create_table.sql
  • V2_0__insert_data.sql

リピータブルマイグレーションSQLファイルの作成

ビュー、プロシージャ、ファンクションなどのオブジェクトのマイグレーションを行いたい場合に使用する。参考
マイグレーションを実行する際に、前回のマイグレーション以降にリピータブルマイグレーションファイルに何らかの変更があった場合、マイグレーションが実行される。
ファイル名は以下の書式となるようにする。

R__<Description>.sql

プレースホルダーを使用する

マイグレーション用のSQLファイル内ではプレースホルダーを使用することができる。
プレースホルダーのプレフィックスサフィックスはそれぞれデフォルトで${}である。
FlyWayがデフォルトで以下のプレースホルダーを用意している。

プレースホルダ 説明
${flyway:defaultSchema} デフォルトスキーマ
${flyway:user} データベースに接続しているユーザー
${flyway:database} 接続しているデータベースの名前
${flyway:timestamp} FlyWayがスクリプトをパースした時間。フォーマット:yyyy-MM-dd HH:mm:ss
${flyway:filename} 現在のスクリプトのファイル名
${flyway:workingDirectory} システムプロパティuser.dirで定義されているユーザーのワークディレクト
${flyway:table} 履歴管理テーブルの名前

以下の方法で独自のプレースホルダーを用意することもできる。

flyway {
     placeholders = ['myplaceholder' : 'value']
}

実際にSQLファイルでプレースホルダーを使用した例を以下に示す。

/* デフォルトで用意されているプレースホルダーの使用例 */
GRANT SELECT ON SCHEMA ${flyway:defaultSchema} TO ${flyway:user};

/* 独自に用意したプレースホルダーの使用例 */
INSERT INTO ${myplaceholder} (name) VALUES ('Mr. T');

SQLファイルの配置場所を変更する

SQLファイルの配置場所を変更したい場合は、build.gradleに locations の設定を追加する。
SQLファイルの配置場所はコンマ区切りで複数個所指定可能。

flyway {
    driver = 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
    url = "$System.env.DATASOURCE_URL"
    user = "$System.env.DATASOURCE_USER_NAME"
    password = "$System.env.DATASOURCE_PASSWORD"
    schemas = ["$System.env.DATASOURCE_SCHEMA_NAME"]
    // ↓追加
    locations = ['filesystem:db/migration']
    // ↑追加
}

ロケーションには以下の4つのプレフィックスのいずれかを付ける。何もつけなかった場合は classpath: がつけられているものとして処理される。

プレフィックス 説明
classpath: クラスパス上のファイルを対象とする。SQLベースとJavaベースの両方のmigrationが含まれる場合がある。
filesystem: ファイルシステム上のディレクトリを対象とする。SQLベースのmigrationのみ含まれる。
s3: AWS S3のバケットが対象となる。SQLベースのmigrationのみ含まれる。s3:<bucket>(/ optionsfolder / subfolder)の形式で記述する。
gcs: Google Cloud Storageのバケットを対象とする。SQLベースのmigrationのみ含まれる。gcs:<bucket>(/ optionsfolder / subfolder)の形式で記述する。

パスの指定にはワイルドカードを使用することもできる。

ワイルドカード 説明
** 0個以上のディレクトリに一致 db/**/test
OK:db/version1.0/test, db/dev/version/1.0/test
NG:db/version1.0/release
* 0個以上の非区切り文字に一致 db/release1.*
OK:db/release1.0, db/release1.123
NG:db/release2.0
? 任意の1つの非区切り文字に一致 db/release1.?
OK:db/release1.0, db/release1.1
NG:db/release1.11

Gradleタスク

flywayBaseline

Flyway用のメタデータテーブル(flyway_schema_history)だけを作成し、データベースのバージョンをbuild.gradleの baselineVersion に設定した値にする。
baselineVersionに値が設定されていなかった場合、バージョンは「1」となる。

>gradlew flywayBaseline

BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

flywayInfo

全てのマイグレーションに関する詳細とステータス情報を出力する。
コマンドの実行結果の例は以下の通り。

>gradlew flywayInfo

> Task :common:flywayInfo
Schema version: << Empty Schema >>
+-----------+---------+-----------------------+----------+---------------------+----------+
| Category  | Version | Description           | Type     | Installed On        | State    |
+-----------+---------+-----------------------+----------+---------------------+----------+
|           | 1       | << Flyway Baseline >> | BASELINE | 2021-09-29 15:15:09 | Baseline |
| Versioned | 1.1     | create table          | SQL      |                     | Pending  |
+-----------+---------+-----------------------+----------+---------------------+----------+


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

実行結果のテーブル各カラム

カラム名 説明
Category マイグレーションのカテゴリ。「Versioned」と「Repeatable」がある。
Versioned:バージョン管理しているマイグレーション
Repeatable:毎回実行するマイグレーション
Version バージョン番号。リピータブルマイグレーションSQLファイルでは空欄となる。
Description マイグレーションの説明。
Type マイグレーションの種類。「BASELINE」、「SQL」、「JDBC」がある。
BASELINE:ベースライン
SQLSQLファイルによるマイグレーション
JDBCJavaファイルによるマイグレーション
Installed On マイグレーションが適用された日時。まだ適用されていない場合は空欄となる。
State マイグレーションの現在の状態。「Baseline」、「Pending」、「Success」、「Failed」、「Ignored」、「Above Target」、「Outdate」、「Superseded」などがある。
Baseline:ベースライン
Pending:マイグレーションがまだ適用されていない
Success:マイグレーションに成功
Failed:マイグレーションに失敗
Ignored:適用済みマイグレーションより前のバージョンの適用されていないマイグレーション
Above Target:Targetプロパティに指定されたよりも大きいバージョン。マイグレーションの対象外

ファイル名に日本語が含まれる場合は以下のようにずれて表示されてしまう。

>gradlew flywayInfo

> Task :common:flywayInfo
Schema version: 1.2
+-----------+---------+-----------------------+----------+---------------------+----------+
| Category  | Version | Description           | Type     | Installed On        | State    |
+-----------+---------+-----------------------+----------+---------------------+----------+
|           | 1       | << Flyway Baseline >> | BASELINE | 2021-09-29 15:15:09 | Baseline |
| Versioned | 1.1     | create table          | SQL      | 2021-09-29 15:18:00 | Success  |
| Versioned | 1.2     | create table          | SQL      | 2021-09-29 15:25:21 | Success  |
| Versioned | 1.3     | テーブル作成                | SQL      |                     | Pending  |
+-----------+---------+-----------------------+----------+---------------------+----------+


BUILD SUCCESSFUL in 7s
1 actionable task: 1 executed

flywayMigrate

スキーマ最新バージョンに移行 する。 スキーマ履歴テーブルが存在しない場合、デフォルトの設定ではスキーマを自動的に作成する。
flywayMigrateコマンド実行後にflywayInfoコマンドでステータスを確認すると、マイグレーションに成功している場合、Successと表示される。

>gradlew flywayMigrate

BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed
>gradlew flywayInfo

> Task :common:flywayInfo
Schema version: 1.1
+-----------+---------+-----------------------+----------+---------------------+----------+
| Category  | Version | Description           | Type     | Installed On        | State    |
+-----------+---------+-----------------------+----------+---------------------+----------+
|           | 1       | << Flyway Baseline >> | BASELINE | 2021-09-29 15:15:09 | Baseline |
| Versioned | 1.1     | create table          | SQL      | 2021-09-29 15:18:00 | Success  |
+-----------+---------+-----------------------+----------+---------------------+----------+

BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

flywayClean

スキーマ内のFlyway用のメタデータテーブル(flyway_schema_history)も含めた全てのオブジェクト(テーブル、ビュー、プロシージャ、トリガー、インデックスなど)をdropする。

>gradlew flywayClean

BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

flywayValidate

データベースのバージョンが最新になっているかどうかを確認する。差異がある場合はエラーが発生する。
以下はタスクの実行例である。

>gradlew flywayValidate

> Task :common:flywayValidate FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':common:flywayValidate'.
> Error occurred while executing flywayValidate
  Validate failed: Migrations have failed validation
  Detected resolved migration not applied to database: 1.3. To fix this error, either run migrate, or set -ignorePendingMigrations=true.
  Need more flexibility with validation rules? Learn more: https://rd.gt/3AbJUZE

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2s
1 actionable task: 1 executed

flywayRepair

マイグレーションに失敗した場合、flywayInfoで確認した時のそのバージョンのStatusがFailedになる。
Failedが残っている状態だとSQLファイルを修正してもマイグレーションは成功しないため、失敗したマイグレーションのレコードをFlywayスキーマの履歴テーブルから削除する。

>gradlew flywayRepair

Community Editionで指定可能なパラメーター

DB接続に関わるパラメーター

パラメータ名 説明 デフォルト
url 接続するDBのURL なし
user 接続するDBのユーザー なし
password パスワード なし
driver jdbcドライバー URLを元に自動で検出
connectRetries データベースへの接続を試みる際の最大再試行回数。
最初の試行で失敗すると1秒待って再試行する。再試行の間隔は回数が増えるごとに2倍になっていく。
0
connectRetriesInterval データベースへの接続を試みる際の再試行の最大時間(秒) 120
initSql 新しいデータベース接続を開いた直後に、その接続を初期化するために実行するSQL なし

スキーマ関連のパラメーター

パラメータ名 説明 デフォルト
createSchemas Flywayがschemasプロパティで指定された存在しないスキーマを作成するかどうか true
defaultSchema Flywayが管理するデフォルトのスキーマ。このスキーマスキーマ履歴テーブルが含まれる。指定する場合は、schemasパラメータに含まれている必要がある。 schemasの最初のスキーマ
schemasの設定がない場合はデータベースのデフォルトのスキーマ
schemas Flywayが管理するスキーマ。コンマ区切りで大文字小文字を区別する。
createSchemasがtrueの場合、リストの中に存在しないスキーマがある場合は作成する。Flywayが作成したスキーマはクリーニング時にスキーマ自体が削除される。
なし

Baselineコマンド関連のパラメーター

パラメータ名 説明 デフォルト
baselineDescription ベースラインを実行する際に、既存のスキーマにタグを付けるための説明 << Flyway Baseline >>
baselineOnMigrate スキーマ履歴テーブルのない空ではないスキーマに対して migrate が実行されたときに、自動的に baseline を呼び出すかどうか。
マイグレーションを実行する前に、baselineVersionでベースライン化され、baselineVersion以上のマイグレーションのみが適用される
false
baselineVersion ベースラインを実行する際に、既存のスキーマにタグを付けるバージョン 1
table Flywayのスキーマ履歴テーブルの名前 flyway_schema_history
tablespace Flywayで使用されるスキーマ履歴テーブルを作成するテーブルスペース。
テーブルスペースの概念をサポートしているデータベースにのみで適用される。
なし

Migrateコマンド関連のパラメーター

パラメータ名 説明 デフォルト
encoding SQLマイグレーションエンコーディング UTF-8
installedBy マイグレーションを適用したとしてスキーマ履歴テーブルに記録されるユーザー名 DBに接続しているユーザー
locations マイグレーションのために再帰的にスキャンする場所のコンマ区切りのリスト classpath:db/migration
failOnMissingLocations locationsオプションで指定した場所が存在しない場合に失敗させるか false
group pending中の全てのマイグレーションを適用する際に、同じトランザクションにまとめるかどうか
(DDLトランザクションをサポートするデータベースでのみ推奨)
false
lockRetryCount マイグレーションの開始時のロックの取得ができなかった場合、1秒間隔でlockRetryCountに指定した回数に達するまで再試行する。
-1を指定すると無期限に再試行を続ける。
50
mixed 同じマイグレーション内で、トランザクションステートメントと非トランザクションステートメントの混在を許可するかどうか。
trueの場合、マイグレーション全体が自動的にトランザクションなしで実行される。
false
outOfOrder マイグレーションを「順不同」で実行できるようにする。
trueの場合、既にバージョン1.0と3.0が適用されている状態でバージョン2.0が見つかった場合、無視されずに適用される。
false
target Flywayがマイグレーションを行う最大のバージョン。
currentまたはlatest以外の値に設定された場合、存在するバージョンである必要がある。
以下の値も設定可能。
・current:スキーマの現在のバージョン
・latest:最も高いバージョンのマイグレーション
latest
resolvers 適用するMigrationsを解決するために、組み込みのものに加えて使用するカスタムMigrationResolverの実装の完全修飾クラス名のコンマ区切りリスト なし
repeatableSqlMigrationPrefix 繰返し可能な SQL マイグレーションのファイル名のプレフィックス
繰り返し可能な SQL マイグレーションのファイル名はデフォルトでは R__My_description.sqlとなる
R
sqlMigrationPrefix SQLマイグレーションのファイル名のプレフィックス
SQLマイグレーションのファイル名はデフォルトでV1.1__My_description.sqlとなる
V
sqlMigrationSeparator SQL マイグレーションのファイル名の区切り文字
SQLマイグレーションのファイル名はデフォルトでV1.1__My_description.sqlとなる
__
sqlMigrationSuffixes SQL マイグレーションのファイル名サフィックスのコンマ区切りリスト .sql

Cleanコマンド関連のパラメーター

パラメータ名 説明 デフォルト
cleanDisabled cleanを無効にするかどうか false
cleanOnValidationError バリデーションエラーが発生したときに、自動的にcleanを呼び出すかどうか false

Validateコマンド関連のパラメーター

パラメータ名 説明 デフォルト
validateMigrationNaming 名前が命名規則と一致しない移行ファイルを無視するかどうか。
falseの場合、無効な名前のファイルは無視され、trueの場合は問題のあるファイルがリストアップされる。
false
validateOnMigrate migrateの実行時に自動的にvalidateを呼び出すかどうか true
ignoreFutureMigrations スキーマの履歴テーブルを読む際に、将来のマイグレーションを無視する。無視されるマイグレーションは、現在のバージョンでは実行していない、アプリケーションのより新しいバージョンによって実行されたマイグレーション true
ignoreIgnoredMigrations スキーマ履歴テーブルを読む際に、無視されたマイグレーションを無視する。無視されるマイグレーションは、現在のバージョンですでに移行されたマイグレーションの間に追加されたマイグレーション false
ignoreMissingMigrations スキーマ履歴テーブルを読む際に、欠落しているマイグレーションを無視する。無視されるマイグレーションは、アプリケーションの古いバージョンで実行されていたが現在のバージョンでは利用できなくなったマイグレーション false
ignorePendingMigrations スキーマ履歴テーブルを読む際に、pendingのマイグレーションを無視する。無視されるマイグレーションは、利用可能だがまだ適用されていないマイグレーション false

プレースホルダーに関わるパラメーター

パラメータ名 説明 デフォルト
placeholderPrefix すべてのプレースホルダーのプレフィックス ${
scriptPlaceholderPrefix すべてのスクリプトマイグレーションプレースホルダーのプレフィックス FP__
placeholderReplacement プレースホルダーを置換するかどうか true
placeholders SQLマイグレーションで置換するプレースホルダ
例えば、key1というプレースホルダーをvalue1という値で置き換えるには、placeholders = ['key1' : 'value1']と設定する
なし
placeholderSuffix すべてのプレースホルダーのサフィックス }
scriptPlaceholderSuffix すべてのスクリプトマイグレーションプレースホルダーのサフィックス __

その他全般的な設定に関わるパラメーター

パラメータ名 説明 デフォルト
callbacks Flywayのライフサイクルに接続するために使用するコールバック実装の完全修飾クラス名、またはこれらのクラスをスキャンするためのパッケージをコンマで区切ったリスト db/callback
configFileEncoding Flyway設定ファイルを読み込む際に使用するファイルエンコーディング UTF-8
configFiles ロードするFlywayの設定ファイル。ワーキングディレクトリからの相対パスを指定する なし
loggers 使用するロガーを指定する。以下の設定が指定可能
・auto:ロガーを自動検出する
・console:標準出力する
・slf4j2:slf4j2ロガーを使用する
・log4j2:log4j2ロガーを使用する
apache-commons:Apache Commons loggerを使用する
auto
skipDefaultCallbacks デフォルトで組み込まれているコールバック(sql)をスキップするかどうか。
trueの場合、カスタムコールバックのみ実行される。
false
skipDefaultResolvers デフォルトで組み込まれているリゾルバ(sqlおよびjdbc)をスキップするかどうか。
trueの場合、カスタムリゾルバのみ実行される。
false