onemuri.space

結局 go の migration ツールは何を使えばよいのか

Goのmigrationツールのデファクトってなくないですか?

2019年9月からGopherの仲間入りを果たしたのですが、golangのmigrationツールって色々あって、どれ使えば良いのか判断しにくいなと思いました。
9月末にmigrationの調査をしてみたので、存在するmigrationツールや、それらのメリットデメリットをまとめてみたいと思います。

ちなみに、筆者はgolangの前はRailsを使っていたので、migrationは最初から付いているものだと思い込んでいました。(そんなわけない)

migrationツール群(star数100以上)

「go migration」などで検索するといくつかのossが出現しました
それらのメリット・デメリットまとめておきます

名称 Star数 バージョン管理可能 CLI dryrun 設定方法
gh-ost 6859 online ok ok online sql
golang-migrate/migrate 2984 up/down ok × sql
sql-migrate 1457 up/down ok ok sql
goose 988 up/down ok × sql
rambler 431 up/down × ok sql
go-gormigrate/gormigrate 355 ? × × go code
DavidHuie/gomigrate 161 up/down × × sql

※ 2019年9月末時点, star数100以下は未調査
※ CLIがないツールは説明しない(CLIなしとか考えられませんでした)

名称 Star数
darwin 87
BurntSushi/migration 64
Boostport/migration 57
migu 50
kamimai 45
carpenter 40
transporter 35
pravasan 24
wallester/migrate 17

どれ使えば良いの?

star数が100以上の中でもgoose、sql-migrate、golang-migrate/migrate、gh-ostならば正直、どれでも良いのでは?ぐらいには考えています。

ただし、gh-ostはmysqlに対してのサポートで、CloudSQLへの対応はできません。
お気をつけください。

有名どころのmigrationツールのサンプルを作ってみた

以下の3つのossについて

  • golang-migrate/migrate
  • sql-migrate
  • goose

dockerを利用して、各種migrationのコマンドを試せるようなサンプルを作ったので、ぜひ参考にしてみてください。
https://github.com/mergitto/go-migrate-sample

golang-migrate/migrate

  • migration file作成(今回はusersテーブル作成)
mkdir migrations
touch migrations/1_create_users_table.up.sql
touch migrations/1_create_users_table.down.sql

upとdownを別々のファイルに記述する点がこのあと説明する、sql-migrategooseとの違いの1つです

  • statusの確認
migrate -database 'mysql://root:mysql@tcp(127.0.0.1:3306)/golang_migrate' -path ./migrations version

1つupしている状態であれば、次のような数字だけが表示されます(少し不親切な気もします)

1
  • migration
-- downファイルの作成
CREATE TABLE IF NOT EXISTS users (id int);

-- migrationを実行
migrate -database 'mysql://root:mysql@tcp(127.0.0.1:3306)/golang_migrate' -path ./migrations up

-- migrationをrollback
migrate -database 'mysql://root:mysql@tcp(127.0.0.1:3306)/golang_migrate' -path ./migrations down

sql-migrate

sql-migrateはconfigの情報はyamlに記述するので、golang-migrate/migrateよりもシンプルなコマンドになります

  • 現在のversionの確認
sql-migrate status

statusの表示内容はgolang-migrate/migrateと違いますね。私はこちらの方が好きです

出力結果
+---------------------------------+---------+
|            MIGRATION            | APPLIED |
+---------------------------------+---------+
| 20190930153619-create_users.sql | no      |
+---------------------------------+---------+
  • migration file作成
sql-migrate new create_users
  • 上記コマンドによって作成されたmigrationファイルの中身の修正
-- +migrate Up
CREATE TABLE IF NOT EXISTS users (id int);

-- +migrate Down
DROP TABLE IF EXISTS users;
  • migration
# migration を実行
sql-migrate up

# migrationをrollback
sql-migrate down

goose

  • statusの確認
goose status

gooseのstatusもgolang-migrate/migrateと比較するとわかりやすいですね
どの環境に対してかも出力してくれます

goose: status for environment 'development'
    Applied At                  Migration
    =======================================
    Pending                  -- 20190930160542_create_users_table.sql
  • migration file作成(今回はusersテーブル作成)
goose create create_users_table sql
  • 作成されたmigrationファイルの中身の修正
-- +migrate Up
CREATE TABLE IF NOT EXISTS users (id int);

-- +migrate Down
DROP TABLE IF EXISTS users;

sql-migrateと同じでup/downを同一ファイルに記述する方式みたいです

  • migration
# migrationを実行
goose up

# migrationをrollback
goose down

結局何使えばよいのか

今回は以下の3つを主に比較しました

  • golang-migrate/migrate
  • sql-migrate
  • goose

これらのツールの違いはほとんど感じられませんでした。sql-migrateがdry-runをすることができる点において少し優秀という印象でしょうか

golang-migrate/migrateはstar数が多かったですが、なぜstar数が多くつくのか理解できませんでした。
私であれば、sql-migrategooseを採用すると思います
以下の点が、その2つの共通点であり、migrationで満たしてほしい条件だと思っています

  • CLIで使える
  • up/downでmigrationができる
  • 環境ごとに設定することができる

というところで、migrationについてのまとめになります。皆さんはいかがでしょうか??

自己紹介用画像

Riki Akagi

2019年からDeNAで働いています。GCP(CloudSQL・GAE・Cloud Function etc)とGoでAPI開発に勤んでいます。睡眠やエンジニアリングに関することに興味を持って過ごしているのでその情報を皆さんに共有していけたらなと思っています。

自己紹介の詳細