はじめに
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ファイルにスキーマ情報を定義します。まずは、下記のようにユーザテーブルを定義します。
1 2 3 4 5 | CREATE TABLE `user` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
準備ができたら、下記のとおりスキーマを更新します。
1 2 3 | $ 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テーブルは下記のとおりです。
1 2 3 4 5 6 7 8 | 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で確認することもできます。
1 2 3 | $ 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行目を追記しました)
1 2 3 4 5 6 7 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); |
発行されるクエリは下記のとおりです。
1 2 3 4 5 6 | $ 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 |
修正後のテーブルは下記のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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は下記のとおり行います。
1 | $ 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について紹介する予定です。