はじめに
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 | CREATETABLE`user`( `id`bigint(20)unsignedNOT NULLAUTO_INCREMENT, `name`varchar(32)DEFAULT'', PRIMARY KEY(`id`) )ENGINE=InnoDBDEFAULTCHARSET=utf8mb4; |
準備ができたら、下記のとおりスキーマを更新します。
1 2 3 | $mysqldef-uyour_user_name mysqldef_test-pyour_password<schema.sql --Apply-- CREATE TABLE`user`( `id`bigint(20)unsignedNOTNULLAUTO_INCREMENT, `name`varchar(32)DEFAULT'', PRIMARY KEY(`id`))ENGINE=InnoDB DEFAULTCHARSET=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 | | | | +-------+---------------------+------+-----+---------+----------------+ 2rows inset(0.00sec) |
また、下記のように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)unsignedNOTNULLAUTO_INCREMENT, `name`varchar(32)DEFAULT'', PRIMARY KEY(`id`))ENGINE=InnoDB DEFAULTCHARSET=utf8mb4; |
スキーマを更新する
次に、userテーブルのスキーマを更新してみましょう。先程作成したschema.sqlを修正して、もう一度コマンドを実行します(4行目、5行目、8行目を追記しました)
1 2 3 4 5 6 7 8 | CREATETABLE`user`( `id`bigint(20)unsignedNOT NULLAUTO_INCREMENT, `name`varchar(32)DEFAULT'', `created_at`DATETIMENOT NULL, `updated_at`DATETIMENOT NULL, PRIMARY KEY(`id`) )ENGINE=InnoDBDEFAULTCHARSET=utf8mb4; ALTERTABLEuserADDINDEXindex_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 NOTNULLAFTER name; ALTER TABLE user ADD COLUMN updated_at datetime NOTNULLAFTER 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 | | +------------+---------------------+------+-----+---------+----------------+ 4rows inset(0.00sec) 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 | | | +-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 2rows inset(0.00sec) |
既存のスキーマを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について紹介する予定です。