Flyway利用手順メモ

flyway利用メモ
# 事前準備

## SQLファイル
* SQLファイルにてデータベースのバージョンを管理する。
* データベースに対応するSQLファイルをバージョンごとに作成する。  
* SQLファイル名にはflyway固有のネーミングルール(書式)が決められている。    


## SQLファイルのネーミングルール(書式)

**``V<Version>__<Description>.sql``**  

### 1. `V` (先頭文字)
* 先頭は必ず `V` から始める(flyway規定)。  

### 2. `<Version>` (バージョン番号)
* バージョン番号を指定する。
* バージョン番号はDB投入時の実行される順番となり、小さい番号から投入される。 
* バージョン番号は一意制約があり、同じバージョンのSQLファイルを用意することはできない。  

基本は以下いずれの組み合わせで指定する。 
※`_`(アンダーバー)は実行時に`.`(ドット)に自動変換される。  
> **バージョン番号** **=** **半角数字**　+ `.`**(ドット)** または `_`**(アンダーバー)**    

```text:sample
1.0
1_2  → 実行時には1.2となる
1.1

------ 実行される順番 ------
1.0 → 1.1 → 1_2 となる

```

### 3. `__` (アンダーバー)
* `<Version>`(バージョン番号)と`<Description>`(説明)との区切り。  
* `_`(アンダーバー)を2つ続ける。  

### 4. `<Description>` (説明)
* バージョンの説明を記述する。  
※`_`(アンダーバー)は実行時に` `(スペース)に自動変換される。  



## SQLファイル名のsample

```text:SQLファイル名(パターン①)
/* パターン① */
V1.01__create_sequence.sql  --> シーケンスのDMLを集約：INSERT  
V1.02__create_table.sql     --> テーブルのDDLを集約：CREATE  
V1.03__initial_data.sql     --> 初期データのDMLを集約：INSERT
```

またはSQLファイル名に環境を明示することでわかりやすくなる。

```text:SQLファイル名(パターン②)
/* パターン②：develop環境であることを明示的にする */  
V1.01__dev_create_sequence.sql  --> develop環境でのシーケンスDMLを集約：INSERT    
V1.02__dev_create_table.sql     --> develop環境でのテーブルDDLを集約：CREATE  
V1.03__dev_initial_data.sql     --> develop環境での初期データDMLを集約：INSERT
```


# 利用コマンド
flywayで利用するコマンド

## マイグレーション : `gradle flywayMigrate`
* マイグレーションを実行する。

## バージョン管理テーブルの作成 : `gradle flywayBaseline -i`
以下の場合において、実行前にバージョン管理用テーブルを作成する必要がある。  

* 初めてflywayのマイグレーションを実行する場合
* flywayによるclean後、マイグレーションを実行する場合
* DBに存在するすべてのテーブルをdropした場合  

## ステータス確認 : `gradle flywayInfo`
* マイグレーションの実行状況ステータスを表示する。  
マイグレーションがどのバージョンまで実行されているかの情報が表示される。    

|            |  ステータス  |
|:----------:|:-----------:|
| Pending    |  実行前 |
| Success    |  成功  |
| Failed     |  失敗  |

## リペア : `gradle flywayRepair`
* マイグレーションの実行ステータスが**Failed**になっているバージョンを**Pending**に戻す。 

バージョン管理のSQLファイルがマイグレーションに実行失敗（一度マイグレーションが失敗）した場合、そのバージョンのステータスが**Failed**になる。 
マイグレーションの実行状態を「Failed」→「Pending」にするために、SQLファイル修正後にリペアする必要がある。  

## 削除 : `gradle flywayClean`
* 全テーブルを削除し、指定のデータベースを再構築する。  


# 実行手順 (マイグレーション)
以下３つのSQLファイルを準備する。

```txt:sql
V1.01__create_sequence.sql   
V1.02__create_table.sql     
V1.03__initial_data.sql    
```

## 1. Baselineを作成する
* はじめにバージョン管理用テーブル(Baseline)を作成する`gradle flywayBaseline -i`。
* Baselineができているか確認する`gradle flywayInfo`。

```console
> gradle flywayBaseline -i

  :flywayBaseline (Thread[Task worker for ':',5,main]) started.

  > Task :flywayBaseline
  Putting task artifact state for task ':flywayBaseline' into context took 0.0 secs.
  Executing task ':flywayBaseline' (up-to-date check took 0.0 secs) due to:
   Task has not declared any outputs.
  Creating Metadata table: "FLYWAY_SAMPLE"."schema_version"
  Successfully baselined schema with version: 1

  :flywayBaseline (Thread[Task worker for ':',5,main]) completed. Took 0.169 secs.

  BUILD SUCCESSFUL in 0s
  1 actionable task: 1 executed




> gradle flywayInfo

  > Task :flywayInfo
  +---------+-----------------------------+---------------------+---------+
  | Version | Description                 | Installed on        | State   |
  +---------+-----------------------------+---------------------+---------+
  | 1       | << Flyway Baseline >>       | 2017-01-10 15:35:01 | Baselin |
  | 1.01    | create sequence     　　　　　　　　　　   | 2017-01-10 15:35:28 | Pending |
  | 1.02    | create table                | 2017-01-10 15:35:30 | Pending |
  | 1.03    | insert initial data         | 2017-01-10 15:35:33 | Pending |
  +---------+-----------------------------+---------------------+---------+
  
  
  BUILD SUCCESSFUL in 0s
  1 actionable task: 1 executed
  
```

## 2. マイグレーション実行
* Baseline作成後、マイグレーションが実行する`gradle flywayMigrate`。  
* 実行後、成功していれば**BUILD SUCCESSFUL**が表示される。  
`flywayInfo`でステータスが**Pending**→**Success**に変更されていることが確認できる。
* 実行により準備したSQLファイル(DDL・DML)がDBに反映される。

```console

> gradle flywayMigrate

  BUILD SUCCESSFUL in 5s
  1 actionable task: 1 executed
  
  
> gradle flywayInfo

  > Task :flywayInfo
  +---------+-----------------------------+---------------------+---------+
  | Version | Description                 | Installed on        | State   |
  +---------+-----------------------------+---------------------+---------+
  | 1       | << Flyway Baseline >>       | 2017-01-10 15:39:28 | Baselin |
  | 1.01    | create sequence     　　　  　　　　　　　 | 2017-01-10 15:40:01 | Success |
  | 1.02    | create table                | 2017-01-10 15:40:02 | Success |
  | 1.03    | insert initial data         | 2017-01-10 15:40:05 | Success |
  +---------+-----------------------------+---------------------+---------+
  
  
  BUILD SUCCESSFUL in 0s
  1 actionable task: 1 executed

```


## 3. リペア
* マイグレーション`gradle flywayMigrate`が失敗した場合、実行前の状態(**Pending**)に戻すためにリペアを実行する`gradle flywayRepair`。  
* 失敗したSQLファイル以降のステータスは、**Pending**→**Failed**となる。  
* 基本的には、失敗元のSQLファイル修正後にリペア`gradle flywayRepair`を実行する。  

```console  
> gradle flywayInfo

  > Task :flywayInfo
  +---------+-----------------------------+---------------------+---------+
  | Version | Description                 | Installed on        | State   |
  +---------+-----------------------------+---------------------+---------+
  | 1       | << Flyway Baseline >>       | 2017-01-10 16:10:21 | Baselin |
  | 1.01    | create sequence     　　　  　　　　　　　 | 2017-01-10 16:11:11 | Success |
  | 1.02    | create table                | 2017-01-10 16:11:12 | Failed  |
  | 1.03    | insert initial data         | 2017-01-10 16:11:15 | Failed  |
  +---------+-----------------------------+---------------------+---------+
  
  
  
> gradle flywayRepair

  BUILD SUCCESSFUL in 5s
  1 actionable task: 1 executed
  
  
  
> gradle flywayInfo

  > Task :flywayInfo
  +---------+-----------------------------+---------------------+---------+
  | Version | Description                 | Installed on        | State   |
  +---------+-----------------------------+---------------------+---------+
  | 1       | << Flyway Baseline >>       | 2017-01-10 16:10:21 | Baselin |
  | 1.01    | create sequence     　　　  　　　　　　　 | 2017-01-10 16:11:11 | Success |
  | 1.02    | create table                | 2017-01-10 16:11:12 | Success |
  | 1.03    | insert initial data         | 2017-01-10 16:11:15 | Success |
  +---------+-----------------------------+---------------------+---------+
  
  
  BUILD SUCCESSFUL in 0s
  1 actionable task: 1 executed
  

```


## 4. 削除(クリーン)
* 削除`gradle flywayClean`実行後、対象DBに存在する全テーブルが削除される。  
※実行後はもとに戻せないため、実行時は注意が必要である！  

```console

> gradle flywayClean 

  BUILD SUCCESSFUL in 1s
  1 actionable task: 1 executed
  
  
> gradle flywayInfo 

  > Task :flywayInfo
  +---------+---------------------+---------------------+---------+
  | Version | Description         | Installed on        | State   |
  +---------+---------------------+---------------------+---------+
  | 1.01    | create sequence     |                     | Pending |
  | 1.02    | create table        |                     | Pending |
  | 1.03    | insert initial data |                     | Pending |
  +---------+---------------------+---------------------+---------+

```

#