golang-migrateを使用してDBのマイグレーションを管理する

プログラミング

こんにちは。いっちー(@tetestkake_blog)です!

この記事では、私が個人的に重宝している「golang-migrate」を紹介したいと思います。

マイグレーションって管理が煩雑になりがちですよね。

golang-migrateを使用すると、以下のようなメリットがあります。

golang-migrateを使うメリット
  • マイグレーションファイルをコード管理できる
  • コマンド1発でマイグレーションを実行したり過去に戻したりできる

このようなメリットがあるので、私が仕事で携わるプロダクトでも採用され活躍しています。

そんな「golang-migrate」を、この記事ではサンプル付きで使い方を解説します。

記事で例示するコードは以下のリポジトリにアップロードしてありますので、よかったら使ってください。

GitHub - yutaiii/go-migrate-sample: go migration sample
go migration sample. Contribute to yutaiii/go-migrate-sample development by creating an account on GitHub.
スポンサーリンク

データベースのマイグレーションとは?

簡単にマイグレーションの説明を紹介します。知ってるよって方は飛ばしてください。

定義は以下の説明がわかりやすいです。

マイグレーションとは、DBに保存されているデータを保持したまま、テーブルの作成やカラムの変更などを行うための機能です。

https://densan-labs.net/tech/codefirst/migration.html
いっちー
いっちー

既存のデータを失わずに、テーブルの追加やカラムの追加などのテーブル定義の変更をおこうことをデータベースのマイグレーションというのですね!

golang-migrateに関して

golang-migrateはGo言語で書かれたデータベースのマイグレーションツールです。

CLIやライブラリとして使用することができます。

以下のような特徴があります。

golang-migrateの特徴
  • 番号つけしたSQLファイルをマイグレーションとして使用
    • どのマイグレーションまで実行したかはコマンド1発でわかる
    • 実行用のupファイル、戻す用のdownファイルを作成する
  • マイグレーションの実行はコマンド1発で完了する

DBの定義や変更をマイグレーションファイルに書き起こしておくことで、

データを保持したままDBマイグレーションを進めたり戻したりする作業がコマンド1発で完了できます。

いっちー
いっちー

〇〇の機能をリリースする前のDBの状態に戻したいんだよな… という場合に威力を発揮します!

golang-migrateはMySQL, MongoDB, Redshift, PostgreSQLなど様々なデータベースに対応しています。

その他の対応DBはこちらをご覧ください。

golang-migrateは以下のリポジトリでOSSとして公開されています。

GitHub - golang-migrate/migrate: Database migrations. CLI and Golang library.
Database migrations. CLI and Golang library. Contribute to golang-migrate/migrate development by creating an account on GitHub.

golang-migrateのインストール

ここからgolang-migrateを実際に使用する手順に関して解説していきます。

macでは以下のコマンドを使用してインストールします。

 brew install golang-migrate

確認します。

$ migrate -version
v4.7.0

インストールされていることを確認できました。

マイグレーションファイルを準備する

upとdown用の2つのファイルを作成します。

upにはマイグレーションを進めるクエリ、

downはマイグレーションを戻す用のクエリを記述します。

今回は以下の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言語がよかったのでおすすめです!

それでは!

コメント

タイトルとURLをコピーしました