Play FrameworkのEvolustionsを試してみた

Play FrameworkのDBマイグレーションツールであるEvolustionsを試してみたので、自動でテーブルが生成されるまでの流れを簡単に説明します。

## 動作環境
OS OSX
Play Framework 2.3.8
データベース PostgreSQL 9.4.5

## DBマイグレーションツールとは？
DBマイグレーションツールとは、データベーススキーマのCI（継続的インテグレーション）を実現することが出来るツールです。
アプリケーションをデプロイする度に、サーバ側のデータベースに接続して、手作業でデータベースのスキーマを構築するのは非常に面倒です。
DBマイグレーションツールを利用することで、アプリケーションをデプロイした際にデータベースのスキーマの差異を識別し、自動でスキーマ構築を行うことが出来るようになります。

## エボリューション・スクリプトを作成
最初に、`conf/evolutions/default`内に`1.sql`を以下の内容で作成します。

```
# Usersテーブルを生成

# --- !Ups
CREATE TABLE users(id serial, name text);

# --- !Downs
DROP TABLE users;
```

`1.sql`のことをエボリューション・スクリプトと呼びます。
スクリプトは以下の2つパートから構成されています。

- Upsパート : 必要なスキーマの生成や変更を行うsqlを記述
- Downsパート : Upsパートを打ち消すsqlを記述

## データベースを作成
ターミナル上で以下のコマンドを実行して、アプリケーションで利用するデータベースを作成します。

```
$ createdb testdb;
```

## application.confの設定
`conf/application.conf`に接続先のデータベースの設定を記述します。

```
db.default.driver = org.postgresql.Driver
db.default.url = "jdbc:postgresql://localhost/testdb"
```

## build.sbtを編集
build.sbtにPostgreSQLのドライバーを追記します。

```
libraryDependencies += "org.postgresql" % "postgresql" % "9.4.1208.jre7"
```

## エボリューション・スクリプトの実行
Play Framewarkを起動し、[localhost:9000](localhost:9000)にアクセスしてみます。
以下の画面が表示されるので、`Apply this script now!`と書かれたボタンをクリックすることで、Upsパートで記述された`CREATE TABLE users(id serial, name text);`が実行され、データベース上にusersテーブルが自動で生成されます。

![スクリーンショット 2016-05-23 23.40.48.png](https://qiita-image-store.s3.amazonaws.com/0/54838/0feaa7b2-99cc-1814-0b53-18f67fcee7e4.png)

データベースのスキーマは以下のようになります。

```
testdb=# \d
 Schema |       Name        |   Type   |  Owner 
--------+-------------------+----------+----------
 public | play_evolutions   | table    | hoge
 public | users             | table    | hoge
 public | users_user_id_seq | sequence | hoge
```

## テーブルのスキーマを変更する
既存のスキーマを新たに変更したい場合は、以下のように`2.sql`を新たに作成し、変更の内容を記述していきます。

```
# Usersテーブルにカラムを追加

# --- !Ups
ALTER TABLE users ADD COLUMN age INTEGER;

# --- !Downs
ALTER TABLE users DROP COLUMN age;
```

[localhost:9000](localhost:9000)にアクセスしてみます。

![スクリーンショット 2016-05-23 23.41.17.png](https://qiita-image-store.s3.amazonaws.com/0/54838/50d22d3b-5915-6d14-ebe6-062d365c46d0.png)

`2.sql`が適用されてusersテーブルにageカラムが追加されます。

```
testdb=# \d users
                            Table "public.users"
 Column  |  Type   |                        Modifiers                      
---------+---------+---------------------------------------------------------
 user_id | integer | not null default nextval('users_user_id_seq'::regclass)
 name    | text    | 
 age     | integer | 
```

## Downsパートの役割について
`1.sql`の記述を以下の内容に変更して、[localhost:9000](localhost:9000)にアクセスしてみます。

```
# Usersテーブルを生成

# --- !Ups
# カラム名をid => user_id に変更する
CREATE TABLE users(user_id serial, name text);

# --- !Downs
DROP TABLE users;
```

![スクリーンショット 2016-05-23 23.41.36.png](https://qiita-image-store.s3.amazonaws.com/0/54838/af7f897d-c9dd-264b-f527-2c933c62c024.png)

Downsパートは既存の`x.sql`に変更があった場合に実行されます。
Downsパートを実行することで、ある特定の状態までデータベースを戻し、Upsパートを実行することで、`x.sql`の変更を自動的にデータベースに適用させることができます。
今回の場合は、`1.sql`が更新されたため、`1.sql`,`2.sql`のDownsパートを実行することでデータベースの状態をの`1.sql`のUpsパートが実行される前の状態まで戻し、再び`1.sql`,`2.sql`のUpsパートが実行されます。

## スクリプトの実行確認をしたくない場合
application.confに以下を追記することで、Playは確認をせずエボリューション・スクリプトを自動実行します。

```
applyEvolutions.default = true  # Ups パートを自動で実行する
-DapplyDownEvolutions.default = true # Downs パートを自動で実行する
```
公式のドキュメントでば以下の理由から`-DapplyDownEvolutions.default = true`を
application.confに記述することは推奨されていません。

 もし Play によって算出されたエボリューション・スクリプトが DOWN エボリューションしか持っていなく、このプロパティが設定されていない場合 Play はこれを実行せず、サーバーも起動しません。

## 参考文献
Evolutions
https://www.playframework.com/documentation/ja/2.3.x/Evolutions