Gooseつかってみた

Gooseとは

GooseとはGo言語で作られたDBマイグレーションツールです。
develop環境やproduction環境など各環境に簡単に設定を変更でき、かなり便利そうなので実際にMySQLで試してみました。

Gooseパッケージの取得

まずは go get して Goose パッケージを取得します。
※ Goをインストールしていない人や、GOPATHを設定していない人は公式ドキュメントを参考に導入してみてください。

$ go get bitbucket.org/liamstask/goose/cmd/goose

dbディレクトリの作成

プロジェクトのルート直下に db ディレクトリを作成します。

$ mkdir db

configファイルの作成

取得したGooseパッケージのサンプルからconfigファイルをコピーします。

$ cp $GOPATH/src/bitbucket.org/liamstask/goose/db-sample/dbconf.yml db/

configファイルの編集

まずは先ほどコピーしてきたconfigファイルの中身をのぞいてみます。
デフォルトで test / develop / production のそれぞれの環境に PostgreSQL の driver が設定してあるのが、なんとなくわかるかと思います。

db/dbconf.yml

test:
    driver: postgres
    open: user=liam dbname=tester sslmode=disable

development:
    driver: postgres
    open: user=liam dbname=tester sslmode=disable

production:
    driver: postgres
    open: user=liam dbname=tester sslmode=verify-full

customimport:
    driver: customdriver
    open: customdriver open
    import: github.com/custom/driver
    dialect: mysql

environment_variable_config:
    driver: $DB_DRIVER
    open: $DATABASE_URL

今回は試すだけなので、developの部分のみ編集してみます。
MySQL のdriverは mymysql とのことなので、 driver には mymysql を設定します。

development:
    driver: mymysql
    open: user=liam dbname=tester sslmode=disable

次に DB に接続するために open の箇所にユーザ名やデータベース名を設定します。
何種類か設定の仕方があるようなので下記を参考にしてみてください。

  • DBNAME/USER/PASSWD
  • unix:SOCKPATH*DBNAME/USER/PASSWD
  • unix:SOCKPATH,OPTIONS*DBNAME/USER/PASSWD
  • tcp:ADDR*DBNAME/USER/PASSWD
  • tcp:ADDR,OPTIONS*DBNAME/USER/PASSWD
  • cloudsql:INSTANCE*DBNAME/USER/PASSWD

参考までに下記のような場合の設定を載せておきます。


Host:localhost
Port:3306
データベース:test
ユーザ:root
パスワード:pass


development:
    driver: mymysql
    open: tcp:localhost:3306*test/root/pass

これでDBの設定は完了です。

DB接続確認

goose status コマンドでDBに問題なく接続できているか確認できます。
これ以降の goose コマンドも全てプロジェクトルートで実行してください。

$ goose status
goose: status for environment 'development'

上記のようにエラーなく表示されたらOKです。

マイグレーションファイルの作成

それではDB接続もOKなので、早速マイグレーションファイルを作りましょう。

マイグレーションファイルは Go または SQL で書けるようなので、今回は簡単なSQLで書いてみます。

それでは、goose create コマンドでマイグレーションファイルを作成します。

$ goose create CreateUsersTable sql
goose: created /project/db/migrations/20151111194459_CreateUsersTable.sql.sql

これだけでマイグレーションファイルのひな型が作成されました。
早速中身を見てみましょう。

db/migrations/20151111194459_CreateUsersTable.sql

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied


-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back

このファイルにCREATE文とDROP文をそれぞれ書きます。

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
CREATE TABLE IF NOT EXISTS `users` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(255) NOT NULL COMMENT 'ユーザ名',
    PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back
DROP TABLE `users`;

これでマイグレーションファイルの準備はできたので、実際に実行してテーブルが作成されるか確認してみましょう。

マイグレーションの実行

goose up コマンドでマイグレーションが実行されます。

$ goose up
goose: migrating db environment 'development', current version: 0, target: 20151111194459
OK    20151111194459_CreateUsersTable.sql.sql

テーブルが作成されているか確認してみます。

mysql> show tables;
+------------------+
| Tables_in_test   |
+------------------+
| goose_db_version |
| users            |
+------------------+
1 row in set (0.00 sec)

mysql> desc goose_db_version;
+------------+---------------------+------+-----+-------------------+----------------+
| Field      | Type                | Null | Key | Default           | Extra          |
+------------+---------------------+------+-----+-------------------+----------------+
| id         | bigint(20) unsigned | NO   | PRI | NULL              | auto_increment |
| version_id | bigint(20)          | NO   |     | NULL              |                |
| is_applied | tinyint(1)          | NO   |     | NULL              |                |
| tstamp     | timestamp           | YES  |     | CURRENT_TIMESTAMP |                |
+------------+---------------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)

mysql> select * from goose_db_version;
+----+----------------+------------+---------------------+
| id | version_id     | is_applied | tstamp              |
+----+----------------+------------+---------------------+
|  1 |              0 |          1 | 2015-11-11 19:49:59 |
|  2 | 20151111194459 |          1 | 2015-11-11 19:49:59 |
+----+----------------+------------+---------------------+
2 rows in set (0.00 sec)

usersテーブルが作成されているのと、マイグレーションのバージョン管理用の goose_db_version テーブルが作成されているのが確認できました。
次に今実行したマイグレーションロールバックしてみます。

$ goose down
goose: migrating db environment 'development', current version: 20151111194459, target: 0
OK    20151111194459_CreateUsersTable.sql

確認してみます。

mysql> show tables;
+------------------+
| Tables_in_test   |
+------------------+
| goose_db_version |
+------------------+
1 row in set (0.00 sec)

mysql> select * from goose_db_version;
+----+----------------+------------+---------------------+
| id | version_id     | is_applied | tstamp              |
+----+----------------+------------+---------------------+
|  1 |              0 |          1 | 2015-11-11 19:49:59 |
|  2 | 20151111194459 |          1 | 2015-11-11 19:49:59 |
|  3 | 20151111194459 |          0 | 2015-11-11 19:53:28 |
+----+----------------+------------+---------------------+
3 rows in set (0.00 sec)

usersテーブルが削除されているのが確認できました。

まとめ

goose をつかうことによって、簡単にマイグレーションすることができました。
最近、Go言語を使ったプロジェクトも増えてきているようなので、goose もこれからさらに活躍する場面が増えるのではないでしょうか。

みんなのGo言語【現場で使える実践テクニック】

みんなのGo言語【現場で使える実践テクニック】