3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

こんにちは、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に全てのモデルを宣言しているので使用してます。

atlas.hcl
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を用意します。

models.go
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分を生成してくれてることが分かりますね。

20230627123246.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を使用してマイグレーションのバージョン管理を行う方法をご紹介しました!
かなりニッチな内容なので、誰得かは分かりませんが役に立てることを願っております🥹

気になったこと(ご感想でも🥴)などございましたら、是非コメントしていただけると嬉しいです!

最後までご覧いただきありがとうございました!センリツでした🤓

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?