こんにちは。いっちー(@tetestkake_blog)です!
この記事では、私が個人的に重宝している「golang-migrate」を紹介したいと思います。
マイグレーションって管理が煩雑になりがちですよね。
golang-migrateを使用すると、以下のようなメリットがあります。
このようなメリットがあるので、私が仕事で携わるプロダクトでも採用され活躍しています。
そんな「golang-migrate」を、この記事ではサンプル付きで使い方を解説します。
記事で例示するコードは以下のリポジトリにアップロードしてありますので、よかったら使ってください。
データベースのマイグレーションとは?
簡単にマイグレーションの説明を紹介します。知ってるよって方は飛ばしてください。
定義は以下の説明がわかりやすいです。
マイグレーションとは、DBに保存されているデータを保持したまま、テーブルの作成やカラムの変更などを行うための機能です。
https://densan-labs.net/tech/codefirst/migration.html

既存のデータを失わずに、テーブルの追加やカラムの追加などのテーブル定義の変更をおこうことをデータベースのマイグレーションというのですね!
golang-migrateに関して
golang-migrateはGo言語で書かれたデータベースのマイグレーションツールです。
CLIやライブラリとして使用することができます。
以下のような特徴があります。
DBの定義や変更をマイグレーションファイルに書き起こしておくことで、
データを保持したままDBマイグレーションを進めたり戻したりする作業がコマンド1発で完了できます。

〇〇の機能をリリースする前のDBの状態に戻したいんだよな… という場合に威力を発揮します!
golang-migrateはMySQL, MongoDB, Redshift, PostgreSQLなど様々なデータベースに対応しています。
その他の対応DBはこちらをご覧ください。
golang-migrateは以下のリポジトリでOSSとして公開されています。
golang-migrateのインストール
ここからgolang-migrateを実際に使用する手順に関して解説していきます。
macでは以下のコマンドを使用してインストールします。
brew install golang-migrate
確認します。
$ migrate -version
v4.7.0
インストールされていることを確認できました。
マイグレーションファイルを準備する
upとdown用の2つのファイルを作成します。
今回は以下の2ファイルを追加しました。
※サンプルのDBはMySQLを使用しています
1_create_table_sample.up.sql
CREATE TABLE IF NOT EXISTS
sample_db.sample(
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME DEFAULT NULL,
PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8mb4;
1_create_table_sample.down.sql
DROP TABLE IF EXISTS
sample_db.sample;
ファイルの先頭の数字はマイグレーションのバージョン番号となり、
この数字を使用して現在どのファイルまでマイグレーションが進んでいるかを判断することができます。
マイグレーションを実行する
プロジェクトのルートで以下のコマンドでマイグレーションを実行します。
$ migrate -source file://db/migrate -database 'mysql://root:root@tcp(127.0.0.1:13306)/sample_db' up
テーブルが作成されていれば成功です!
バージョンを確認してみましょう。
$ migrate -source file://db/migrate -database 'mysql://root:root@tcp(127.0.0.1:13306)/sample_db' version
1
マイグレーションの番号が1と表示されていますね!
マイグレーションを戻す
次はマイグレーションを戻してみましょう。
新しいマイグレーションファイルを追加します。
2_insert_sample_data.up.sql
INSERT INTO sample
(name)
VALUES
('hoge'),
('fuga'),
('piyo');
2_insert_sample_data.down.sql
TRUNCATE TABLE sample;
マイグレーションを上げます。
$ migrate -source file://db/migrate -database 'mysql://root:root@tcp(127.0.0.1:13306)/sample_db' up
2/u insert_sample_data (356.557137ms)
$ migrate -source file://db/migrate -database 'mysql://root:root@tcp(127.0.0.1:13306)/sample_db' version
2
以下のコマンドでマイグレーションを下げることができます。
migrate -source file://db/migrate -database 'mysql://root:root@tcp(127.0.0.1:13306)/sample_db' down 1
最後の数字はmigrationを何個戻すかを指定しています。
今回の場合はマイグレーションを1つ戻します。
数字を指定しないと全てのマイグレーションを戻す挙動なので注意が必要です。
$ migrate -source file://db/migrate -database 'mysql://root:root@tcp(127.0.0.1:13306)/sample_db' down
Are you sure you want to apply all down migrations? [y/N]
マイグレーションを進める際にも同様で、最後にどれだけマイグレーションを進めるかを指定できます。

マイグレーションを進める際にはupコマンドを、
戻す際にはdownコマンドを使うというシンプルな構造なので、
とても簡単にマイグレーションの管理ができますね!
終わりに
いかがだったでしょうか?
golang-migrateを使用することでマイグレーションファイルをコード管理できて、
DBのマイグレーションを進めたり戻したりが簡単になるため、是非使ってみてください!

Go言語の学習には基礎からわかるGo言語がよかったのでおすすめです!
それでは!
コメント