Golang製DBマイグレーションツール「sql-migrate」を使ってみる

今回は以下記事の続きでDBマイグレーションツールの導入を行おうと思います。

【gRpc】golangでgRpcサーバを立ててみる

以前以下の記事ではJava製のマイグレーションツール「Flyway」について書きましたが、Go製ツールも使ってみたかったので今回は「sql-migrate」を使用することにしました。

また、golang用のORMとして人気のある「gorm」ではstructからマイグレーションを行うこともできますが、DBのダウングレードができないのでDBマイグレーションツールとしての採用は見送りました。

環境情報

OS: Windows10 64bit
golang: v1.15.3
sql-migrate: v1.0.0
mysql: v5.7.25

環境変数「APPS=/c/dev」を設定しています。(アプリの配置先)

※コマンドの実行は基本的にgit bashで行っているのでlinuxコマンドになっています。

サンプルコードのリポジトリ

今回使用したサンプルは以下のリポジトリに配置しています。

https://github.com/i-shinya/grpc-client-server-sample

今回までのサンプルコードは以下のコミットで確認できます。

今回までのコード

Golang製DBマイグレーションツール「sql-migrate」を使ってみる

sql-migrate用のディレクトリの準備

sql-migrate用にディレクトリを作成します。ツール系のディレクトリとして用意していたtoolsディレクトリは以下に新たにディレクトリを作成し、以下のようなディレクトリ構成となりました。

.
`-- tools
    |-- grpc ・・・ grpc関連の設定ファイルなどを配置する(内容は省略)
    `-- db ・・・ db操作関連の設定ファイルなどを配置する
        `-- migrate ・・・ DBマイグレーション用の設定ファイルを配置する
            `-- migrations ・・・ マイグレーション用のSQLファイルを配置する

sql-migrateをgo getする

以下のコマンドでsql-migrateをgo getします。

go get -v github.com/rubenv/sql-migrate/...

Windowsだと設定を変更していなければ以下のパスがグローバルGOPATHとなっているので、こちらを環境変数pathへ追加してください。

%USERPROFILE%\go\bin

sql-migate用の設定ファイルを追加する

tools/db/migrate配下にdbconfig.ymlというsql-migrate用の設定ファイルを作成し、以下のような記載にします。

development:
  dialect: mysql
  dir: migrations
  datasource: sample_user:sample_user_pass@tcp(127.0.0.1)/sample_db?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true

こちらのサンプルでは開発用の設定のみ追加しています。また、DB関連の設定は以下のようになっています。(DBやユーザ・パスワードは事前に設定してください。)

DBMS: mysql
接続先: localhost
DB名: sample_db
ユーザ名: sample_user
パスワード: sample_user_pass

DBマイグレーションファイルを作成する

sql-migrateでは以下コマンドでマイグレーション用のファイルを新規作成できます。以下のコマンドのcreate_userはファイル名です。

cd $APPS/grpc-client-server-sample/tools/db/migrate/

sql-migrate new create_user

こちらを実行するとtools/db/migrate/migrations配下にファイルが作成されます。

今回の場合は20201126004647-create_user.sqlというファイル名になりました。自動でタイムスタンプがprefixになります。

sql-migrateはこのタイムスタンプ順にSQLを実行していくようです。

DBマイグレーションファイルに追記する

上記で作成したファイルは以下のようになっています。


-- +migrate Up

-- +migrate Down

「– +migrate Up」と記載がある下に実行したいSQLを記載します。

また、「– +migrate Down」と記載がある下にそのSQLを打ち消すSQLを記載します。

今回は試しに以下のような記載としました。

-- +migrate Up
CREATE TABLE IF NOT EXISTS user (
    id int(15) AUTO_INCREMENT,
    user_name varchar(100),
    PRIMARY KEY (id));

-- +migrate Down
DROP TABLE IF EXISTS user;

DBマイグレートする

以下のコマンドでマイグレーションを実行します。

cd $APPS/grpc-client-server-sample/tools/db/migrate/

sql-migrate up

実行すると「Applied 1 migration」と表示されるです。これでマイグレーションは完了です。DBを確認するとUSERテーブルが作成されているはずです。

DBのマイグレーション状況を確認する

以下のコマンドでDBに適用されているマイグレーションを確認できます。

cd $APPS/grpc-client-server-sample/tools/db/migrate/

sql-migrate status

MIGRATIONとAPPLIEDが表示されます。MIGRATIONにはマイグレーションファイルの一覧が、APPLIEDには適用されている場合はタイムスタンプが、適用されていない場合はnoという文字が表示されます。

マイグレーションファイルを追加する

ついでにマイグレーションファイルを追加して、先程マイグレートした結果できたUSERテーブルにカラムを追加してみようと思います。まずは以下コマンドでマイグレーションファイルを追加!!

cd $APPS/grpc-client-server-sample/tools/db/migrate/

sql-migrate new add_email_column

作成されたファイルに以下の記載をし、emailカラムを追加します。


-- +migrate Up
ALTER TABLE user ADD email varchar(100);

-- +migrate Down
ALTER TABLE user DROP COLUMN email;

再び以下コマンドでマイグレートします。

cd $APPS/grpc-client-server-sample/tools/db/migrate/

sql-migrate up

カラム追加できました!sql-migrate statusを実行すると一覧にファイルが追加されているはずです。

DBをダウングレードする

最後に先ほど適用したマイグレーションをダウングレードして、カラム追加を打ち消します。

ダウングレードには以下コマンドを実行します。

cd $APPS/grpc-client-server-sample/tools/db/migrate/

sql-migrate down

emailカラムが削除されているはずです!

 

downコマンドでは前回実行したupコマンドを打ち消すことができます。upコマンドの実行が実質バージョンとなるわけです。(もしかしたらマイグレーションファイルを指定してそこまでupやdownすることもできるかもしれないです。そのうち調べます)

また、upコマンドは適用されていない全てのマイグレーションファイルを実行していくようです。

 

開発環境では何度もマイグレーションをするので開発環境でもDBのバージョンを管理したい場合はあまり適していないツールかもしれないです。その場合はFlywayとかを使うのが良いかもです。

参考

https://github.com/rubenv/sql-migrate

https://qiita.com/k-kurikuri/items/946e2bf8c79176ef3ff0

https://qiita.com/koji_zep/items/b024db36a5d55cb98a62