flywayを触ってみたメモ


flywayはDBのスキーマをバージョン管理出来るツール。
RoRのDBマイグレーションをツールとして切り出した感じ？

## 構成

+ Flyway 3.2.1
+ MySQL 5.6.26


## 準備

スキーマ定義ファイルを入れておく`sql`ディレクトリを作る。
flywayがインストールされてるディレクトリ直下のsqlに定義ファイル入れておけば自動で認識してくれるようになるが、きっとそんなことはしないので自分で作る。

```bash
$ mkidr sql
```

flywayで管理する`flyway_test`というDBを作成する。

```sql
mysql> create database flyway_test;
```

とりあえず試す。
`-url`に接続DB情報を指定する。内部的にJavaが動いてるっぽく、`jdbc:ドライバ名(DBの種類):ホスト:ポート/DB名`という感じで指定する。
指定できるドライバは公式サイトのsupported databasesにある
[Flyway &bull; Database Migrations Made Easy.](http://flywaydb.org/documentation/)
`-user`にはDBの接続ユーザー名を指定する。
`-locations`にスキーマ定義ファイルを入れているディレクトリを指定する。コマンドラインツールのくせにJavaのクラスパスでも指定できるっぽいが、きっとそんなことはしないので`filesystem:./sql`みたいな感じでさっき作ったsqlディレクトリを指定する。

```bash
$ flyway -url=jdbc:mysql://localhost/flyway_test -user=root -locations=filesystem:./sql info
Flyway 3.2.1 by Boxfuse

Database: jdbc:mysql://localhost:3306/flyway_test (MySQL 5.6)

+---------+-------------+---------------------+---------+
| Version | Description | Installed on        | State   |
+---------+-------------+---------------------+---------+
| No migrations found                                   |
+---------+-------------+---------------------+---------+
```

DB作っただけなのでまだ何もない。

## マイグレーション

スキーマ定義ファイルを`sql`以下に作成。

```sql:sql/V1__create_user_table.sql
create table user (
    id int primary key auto_increment,
    name varchar(128)
);
```

この状態でinfoを出すとまだマイグレーションが実行されてないとの表示が出る。

```bash
$ flyway -url=jdbc:mysql://localhost/flyway_test -user=root -locations=filesystem:./sql info
Flyway 3.2.1 by Boxfuse

Database: jdbc:mysql://localhost:3306/flyway_test (MySQL 5.6)

+---------+-------------------+---------------------+---------+
| Version | Description       | Installed on        | State   |
+---------+-------------------+---------------------+---------+
| 1       | create user table |                     | Pending |
+---------+-------------------+---------------------+---------+
```

`migrate`コマンドでマイグレーションが実行される。

```bash
$ flyway -url=jdbc:mysql://localhost/flyway_test -user=root -locations=filesystem:./sql migrate
Flyway 3.2.1 by Boxfuse

Database: jdbc:mysql://localhost:3306/flyway_test (MySQL 5.6)
Validated 1 migration (execution time 00:00.009s)
Creating Metadata table: `flyway_test`.`schema_version`
Current version of schema `flyway_test`: << Empty Schema >>
Migrating schema `flyway_test` to version 1 - create user table
Successfully applied 1 migration to schema `flyway_test` (execution time 00:00.290s).
```

`info`で出すと確かにされているっぽい。

```bash
$ flyway -url=jdbc:mysql://localhost/flyway_test -user=root -locations=filesystem:./sql info
Flyway 3.2.1 by Boxfuse

Database: jdbc:mysql://localhost:3306/flyway_test (MySQL 5.6)

+---------+-------------------+---------------------+---------+
| Version | Description       | Installed on        | State   |
+---------+-------------------+---------------------+---------+
| 1       | create user table | 2015-10-24 22:24:40 | Success |
+---------+-------------------+---------------------+---------+
```

mysqlに入って確認してみる。

```sql
mysql> show tables;
+-----------------------+
| Tables_in_flyway_test |
+-----------------------+
| schema_version        |
| user                  |
+-----------------------+
2 rows in set (0.00 sec)

mysql> describe user;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(128) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
```

schema_versionはflywayが管理するテーブルスキーマのメタデータとかが入ってる。

もう一個作ってみる。

```sql:sql/V2__create_item_table.sql
create table item (
    id int primary key auto_increment,
    name varchar(128),
    price int
);
```

```bash
$ flyway -url=jdbc:mysql://localhost/flyway_test -user=root -locations=filesystem:./sql info
Flyway 3.2.1 by Boxfuse

Database: jdbc:mysql://localhost:3306/flyway_test (MySQL 5.6)

+---------+-------------------+---------------------+---------+
| Version | Description       | Installed on        | State   |
+---------+-------------------+---------------------+---------+
| 1       | create user table | 2015-10-24 22:24:40 | Success |
| 2       | create item table |                     | Pending |
+---------+-------------------+---------------------+---------+
```

まだmigrateしてないのでstatusがpendingになってる。

```bash
$ flyway -url=jdbc:mysql://localhost/flyway_test -user=root -locations=filesystem:./sql migrate
Flyway 3.2.1 by Boxfuse

Database: jdbc:mysql://localhost:3306/flyway_test (MySQL 5.6)
Validated 2 migrations (execution time 00:00.063s)
Current version of schema `flyway_test`: 1
Migrating schema `flyway_test` to version 2 - create item table
Successfully applied 1 migration to schema `flyway_test` (execution time 00:00.124s).

$ flyway -url=jdbc:mysql://localhost/flyway_test -user=root -locations=filesystem:./sql info
Flyway 3.2.1 by Boxfuse

Database: jdbc:mysql://localhost:3306/flyway_test (MySQL 5.6)

+---------+-------------------+---------------------+---------+
| Version | Description       | Installed on        | State   |
+---------+-------------------+---------------------+---------+
| 1       | create user table | 2015-10-24 22:24:40 | Success |
| 2       | create item table | 2015-10-24 23:16:58 | Success |
+---------+-------------------+---------------------+---------+
```

migrateしてやるとstatusはsuccessになる。

## コンフィグファイル

flyway実行時にオプションでいちいち接続情報を指定するのも面倒なのでコンフィグファイルを作ってそれを元によしなにやってもらう。

```flyway.conf
flyway.url=jdbc:mysql://localhost/flyway_test
flyway.user=root
flyway.locations=filesystem:./sql 
```

こんな感じで作っておくと

```bash
$ flyway info
Flyway 3.2.1 by Boxfuse

Database: jdbc:mysql://localhost:3306/flyway_test (MySQL 5.6)

+---------+-------------------+---------------------+---------+
| Version | Description       | Installed on        | State   |
+---------+-------------------+---------------------+---------+
| 1       | create user table | 2015-10-24 22:24:40 | Success |
| 2       | create item table | 2015-10-24 23:16:58 | Success |
+---------+-------------------+---------------------+---------+
```

という感じでオプション付けずに実行できるのですっきりする。

## その他

元がJava用のツールだったとはいえ、コマンドラインツールのくせにJavaが見え隠れしているのがカッコ悪い。
スキーマのアップグレードはできるがダウングレードはできないので複数人開発とかで、手元のスキーマ定義を作ったり戻したり(ソースコードのバージョン戻すとかで)した時にどうすればいいんだろう。