はじめに
こんにちは、H×Hのセンリツ大好きエンジニアです。(同担OKです😉)
今回はGoのマイグレーションツールAtlasの始め方について記事を書きました!
(記事キャンペーンに投稿してQiitaオリジナルグッズが欲しいのは内緒🤫)
背景として、gormをORMに使用していたのですが、マイグレーションをバージョン管理したいな。。。という願望がありましたのでAtlasを始めました!
Atlasとは?
公式サイト:atlas
Atlasは、データベースのマイグレーションツールになります。
バージョンマイグレーションと、宣言的マイグレーションの2通りが使用できる&多機能になっているのでかなりオススメです!
- バージョンマイグレーション:マイグレーションをバージョン管理する
- 宣言的マイグレーション:現状のスキーマファイルとDBを比較して内部的に変更を検知した上でマイグレーションが実行される
様々な言語のORMに対応していますが、今回はgormでバージョンマイグレーションを行います。
また、MySQLを始めとした様々なデータベースをサポートしてます。
Atlasのセットアップ
MacOSとLinuxの場合は以下のコマンドでインストールできます
curl -sSf https://atlasgo.sh | sh
次に、atlas.hcl
というファイルを作成します。
こちらのファイルは、DBスキーマを宣言するために使用されます。
※この方法はgorm.Modelが同一パッケージ内に全て存在している場合のみ使用可能です
自分の場合は、domain/models
に全てのモデルを宣言しているので使用してます。
data "external_schema" "gorm" {
program = [
"go",
"run",
"-mod=mod",
"ariga.io/atlas-provider-gorm",
"load",
"--path", "./domain/models",
"--dialect", "mysql", // | postgres | sqlite | sqlserver
]
}
env "gorm" {
src = data.external_schema.gorm.url
dev = "docker://mysql/8/dev"
migration {
dir = "file://migrations"
}
format {
migrate {
diff = "{{ sql . \" \" }}"
}
}
}
次に、gorm.Modelsを用意します。
package models
import "gorm.io/gorm"
type User struct {
gorm.Model
Name string
Pets []Pet
}
type Pet struct {
gorm.Model
Name string
User User
UserID uint
}
Atlasでのバージョンマイグレーションと適用
この構造体から、マイグレーションファイルを作成します。
Atlasでは、以下のコマンドでマイグレーションファイルが生成されます。
atlas migrate diff --config file://atlas.hcl --env gorm
すると、migrations
ディレクトリが作成され、中にマイグレーションのバージョンファイルとそのハッシュ値を管理するファイルが作成されます。
migrations
|-- 20230627123246.sql <- バージョン管理されたマイグレーションファイル
`-- atlas.sum <- 勝手に変更出来ないように、ハッシュ値で管理されている
0 directories, 2 files
これのありがたい所が、自分の手で勝手にマイグレーションファイルを書き換えてしまってもハッシュ値が異なればatlas
コマンドが動作しなくなるため、誤作動と改ざんを防いでくれます。😉
また、マイグレーションファイルの中身を覗くと以下のように、きちんと構造体からSQL分を生成してくれてることが分かりますね。
-- Create "users" table
CREATE TABLE `users` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`created_at` datetime(3) NULL,
`updated_at` datetime(3) NULL,
`deleted_at` datetime(3) NULL,
`name` longtext NULL,
PRIMARY KEY (`id`),
INDEX `idx_users_deleted_at` (`deleted_at`)
) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
-- Create "pets" table
CREATE TABLE `pets` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`created_at` datetime(3) NULL,
`updated_at` datetime(3) NULL,
`deleted_at` datetime(3) NULL,
`name` longtext NULL,
`user_id` bigint unsigned NULL,
PRIMARY KEY (`id`),
INDEX `fk_users_pets` (`user_id`),
INDEX `idx_pets_deleted_at` (`deleted_at`),
CONSTRAINT `fk_users_pets` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
後は、生成されたマイグレーションファイルをDBに適用するだけなので、以下のコマンドで実行します。
※公式ではAtlas Cloudを使用していますが、わざわざGUIで確認しに行くのも手間なので、CLIで完結させます
atlas migrate apply --url "自身のMySQLパス"
これでDBを見てみると、きちんと追加されてますね🫣
mysql> show tables;
+--------------------+
| Tables_in_database |
+--------------------+
| users |
| pets |
+--------------------+
2 rows in set (0.01 sec)
おわりに
gormとAtlasを使用してマイグレーションのバージョン管理を行う方法をご紹介しました!
かなりニッチな内容なので、誰得かは分かりませんが役に立てることを願っております🥹
気になったこと(ご感想でも🥴)などございましたら、是非コメントしていただけると嬉しいです!
最後までご覧いただきありがとうございました!センリツでした🤓