カテゴリー: BackEnd

Go言語で使えるmigrationライブラリ

はじめに

Go言語の連載8回目です。今回はGo言語でWeb開発をする際に使うDB関連のライブラリとして、migrationに絞って調べてみました。

migrationライブラリ

Go言語のmigrationライブラリをいくつかピックアップしました。これらのライブラリを利用することで、データベースに保存されているデータを保持したまま、テーブルの作成やカラムの変更などが行なえます。それでは、各ライブラリの特徴を簡単に紹介します。より詳しい説明はこちらご覧ください。

goose

gooseはGitHub版とBitbucket版でソースコードが異なるようです。GitHub版ではプレフィックスとして5桁の数値が追加され、Bitbucket版ではプレフィックスとしてタイムスタンプ追加されます。環境ごとに設定ファイルを作ることができます(執筆時点でのスター数は575)

sql-migrate

sql-migrateはgooseと同じようなことができます。対応するドライバはgooseより多いようです(執筆時点でのスター数は1,114)

migu

miguはGoのstructをテーブル定義として使用するため、わざわざマイグレーションファイルを書かかなくて良いという利点があります。反面、ロールバックはできません(執筆時点でのスター数は42)

pop

popはコマンドでデータベースを作れます。また、created_atとupdated_atが自動的に追加され、popのORMを使う場合は自動的に更新されます。ただし、2つのファイルにUPとDOWNを分けて書く必要があります(執筆時点でのスター数は476)

sqldef

sqldefは他のライブラリと異なりスキーマファイルの差分を修正するSQLを発行します。それにより、シンプルにスキーマを管理することができます(執筆時点でのスター数は313)

sqldefを使ってみる

今回はスキーマの管理がシンプルなsqldefを使ってみます。

導入

こちらのように自分にあったバイナリをダウンロードします。今回はMac用のmysqlder_darwin_amd64.zipをダウンロードします。ダウンロード後、中身を任意のディレクトリに移動させます(今回は$GOROOT/binに移動させました)

テーブルを追加

準備ができたところで、早速データベースにテーブルを追加してみます。sqldefではschema.sqlファイルにスキーマ情報を定義します。まずは、下記のようにユーザテーブルを定義します。

CREATE TABLE `user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

準備ができたら、下記のとおりスキーマを更新します。

$ mysqldef -uyour_user_name mysqldef_test -pyour_password < schema.sql
-- Apply --
CREATE TABLE `user` (  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  `name` varchar(32) DEFAULT '',  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

すると、データベース(mysqldef_test)にuserテーブルが追加されます。追加されたuserテーブルは下記のとおりです。

mysql> desc user;
+-------+---------------------+------+-----+---------+----------------+
| Field | Type                | Null | Key | Default | Extra          |
+-------+---------------------+------+-----+---------+----------------+
| id    | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(32)         | YES  |     |         |                |
+-------+---------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

また、下記のようにdry runで確認することもできます。

$ mysqldef -uyour_user_name mysqldef_test -pyour_password --dry-run < schema.sql
-- dry run --
CREATE TABLE `user` (  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  `name` varchar(32) DEFAULT '',  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

スキーマを更新する

次に、userテーブルのスキーマを更新してみましょう。先程作成したschema.sqlを修正して、もう一度コマンドを実行します(4行目、5行目、8行目を追記しました)

CREATE TABLE `user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT '',
  `created_at` DATETIME NOT NULL,
  `updated_at` DATETIME NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE user ADD INDEX index_name(name);

発行されるクエリは下記のとおりです。

$ mysqldef -uyour_user_name mysqldef_test -pyour_password --dry-run < schema.sql
-- dry run --
ALTER TABLE user ADD COLUMN created_at datetime NOT NULL AFTER name;
ALTER TABLE user ADD COLUMN updated_at datetime NOT NULL AFTER created_at;
ALTER TABLE user ADD INDEX index_name(name);
Hirokis-MacBook-Pro:mysqldef_sample Hiroki$ vi schema.sql

修正後のテーブルは下記のとおりです。

mysql> desc user;
+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| id         | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(32)         | YES  | MUL |         |                |
| created_at | datetime            | NO   |     | NULL    |                |
| updated_at | datetime            | NO   |     | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> show index from user;
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| user  |          0 | PRIMARY    |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| user  |          1 | index_name |            1 | name        | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)

既存のスキーマをexportする

既存のスキーマのexportは下記のとおり行います。

$ mysqldef -uyour_user_name your_database_name -pyour_password --export > schema.sql

対応しているコマンド一覧

sqldefが対応しているコマンドは下記のとおりです(MySQLのみ載せてあります。PostgreSQLについてはこちらをご覧ください)

  • CREATE TABLE, DROP TABLE
  • ADD COLUMN, CHANGE COLUMN, DROP COLUMN
  • ADD INDEX, ADD UNIQUE INDEX, CREATE INDEX, CREATE UNIQUE INDEX, DROP INDEX
  • ADD PRIMARY KEY, DROP PRIMARY KEY
  • ADD FOREIGN KEY, DROP FOREIGN KEY

さいごに

今回はGo言語でのマイグレーション管理のためのライブラリを紹介しました。次回はORMについて紹介する予定です。

おすすめ書籍

      

Hiroki Ono

シェア
執筆者:
Hiroki Ono
タグ: golangGo言語

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

2週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

4週間 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前