1
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?

【Go言語】GORM + Atlasを実務視点でまとめてみた

1
Posted at

はじめに

この記事で扱う範囲は、AutoMigrateから移行、差分生成〜適用までです。
CI/本番適用は構成次第なので深く触れません。
周辺記事を軽く漁ってみたのですが公式チュートリアルのハンズオンレベルの内容は出てきましたが、実務レベルの設定内容や実行コマンドがまとまっている記事が見当たらなかったのでまとめました。

移行前の課題

個人開発しているアプリのバックエンドにGoを採用しており、ORMとしてGORMを使用しています。
GORMのAutoMigrateでマイグレーションをしていましたが、本番運用を考えるとバージョン管理ができないことは致命的です。
そこでGORMの公式ドキュメントにAtlasが紹介されているのを見つけ使ってみることにしました。

Atlasとは

Atlasは宣言型のスキーマ管理とバージョン管理を両立した、言語非依存のツールです。
GORMがサポートされており、GORMプロバイダーをインストールして組み合わせることで、構造体とタグからマイグレーションファイルを生成できます。

前提/構成

  • ローカル環境:Docker(DevContainer) ※ローカル環境構築周りは主題からそれるため、本記事ではあつかいません。
  • RDB:MySQL8系
  • ORM:GORM
  • バージョン管理:Atlas
  • Atlas GORM プロバイダー モード:スタンドアローン ※セットアップにて解説します。

セットアップ

公式ドキュメントにてスタートガイドが記載されています。
https://atlasgo.io/guides/orms/gorm/getting-started

スタンドアローンモードとGoプログラムモード

Atlas GORMプロバイダーには「スタンドアローン」と「Goプログラム」の2モードがあります。
モデルが単一パッケージにまとまっている場合はスタンドアローン、分割されている場合はGoプログラムモードが向いています。
私は単一パッケージのため、スタンドアローンで実施しました。

コマンドインストール

Atlas CLI の最新リリースをダウンロードしてインストールするには、ターミナルで次のコマンドを実行するだけです。

curl -sSf https://atlasgo.sh | sh

GORM Atlasプロバイダーをインストール

次のコマンドを実行してプロバイダーをインストールします。

go get -u ariga.io/atlas-provider-gorm

設定ファイル作成

プロジェクトディレクトリに、atlas.hclを次の内容で作成します。

data "external_schema" "gorm" {
  program = [
    "go",
    "run",
    "-mod=mod",
    "ariga.io/atlas-provider-gorm",
    "load",
    "--path", "./path/to/models",
    "--dialect", "mysql", // | postgres | sqlite | sqlserver
  ]
}
env "gorm" {
  // 理想スキーマ(GORMモデル)
  src = data.external_schema.gorm.url

  // diff 計算用(空DB推奨)
  // 注意:私はatlasというDATABASEを同じスキーマに作成しています。
  dev = "mysql://root:password@mysql:3306/atlas?charset=utf8mb4&parseTime=true&loc=Local"

  // 適用先(実DB)
  url = "mysql://root:password@mysql:3306/development?charset=utf8mb4&parseTime=true&loc=Local"

  dev = "docker://mysql/8/dev"
  migration {
    dir = "file://migrations"
  }
  format {
    migrate {
      diff = "{{ sql . \"  \" }}"
    }
  }
}

tools.goを作成

tools.go という名前で下記内容でファイルを作成してください。

//go:build tools
package main // 実プロジェクトのパッケージ名に合わせてください

import _ "ariga.io/atlas-provider-gorm/gormschema"

依存関係を整理

以下のコマンドを実行してください。

go mod tidy

セットアップの確認

次に、コマンドを実行して目的のスキーマ (GORM モデル) を検査し、Atlas が目的のスキーマを読み取ることができることを確認します。

モデル例として、下記内容のファイルを作成してください。

type User struct {
    gorm.Model
    Name    string
    Age     int
}

下記コマンドを実行してください。

src は external_schema が吐く理想状態です。
inspect --url env://src はDBではなく理想状態のスキーマを見るためです。

atlas schema inspect --env gorm --url "env://src"

以下のような結果が得られます。

table "users" {
  schema = schema.dev
  column "id" {
    null           = false
    type           = bigint
    unsigned       = true
    auto_increment = true
  }
  column "created_at" {
    null = true
    type = datetime(3)
  }
  column "updated_at" {
    null = true
    type = datetime(3)
  }
  column "deleted_at" {
    null = true
    type = datetime(3)
  }
  column "name" {
    null = true
    type = longtext
  }
  column "age" {
    null = true
    type = bigint
  }
  primary_key {
    columns = [column.id]
  }
  index "idx_users_deleted_at" {
    columns = [column.deleted_at]
  }
}
schema "dev" {
  charset = "utf8mb4"
  collate = "utf8mb4_0900_ai_ci"
}

以上でセットアップは完了です。

実務で詰まりやすいポイント

有料プランについて

価格

価格はこちらに記載されています(2026年2月時点)。
https://atlasgo.io/pricing
Atlas Pro (Team)の場合:

  • メンバー一人当たり$9/月
  • CIを使用するなら$59/月
  • DB監視を行うなら$39/月

Atlas Enterpriseは価格が明記されていないので各自問い合わせてください。

無料板と有料板の違い

各種RDBごとこちらに記載されています。
https://atlasgo.io/features#pro
https://atlasgo.io/features#database-features

有料版が必要な機能(一部抜粋)

  • atlas migrate lintコマンド
  • CI関連機能
  • ビュー、マテリアライズド・ビュー
  • RLS(Row Level Security)
  • 全文検索インデックス

制約が厳しいように感じるので、DB設計も踏まえてしっかり検討されたほうが良いと思います。
※最新情報を必ず確認してください。

設定ファイルについて

DBの向き先設定について

atlas.hclファイルにdev/url属性を定義して指定する必要があります。
dev属性は下記公式ドキュメントに記載されています。
https://atlasgo.io/concepts/dev-database

一部のコマンドでは、 「Dev Database」を指すURLが必要です。これは通常、Atlasがユーザーのスキーマ、マイグレーションなどの処理と検証に使用する、一時的なローカルデータベースです。

url属性はマイグレーションの適用先を指定します。

ハードコーディングについて

自前で用意しているDBを使用する場合、dev/urlの値に機微情報が入ってしまうと思います。
公式ドキュメントで環境変数から値を取得する方法や、format関数の使い方が説明されています。
https://atlasgo.io/atlas-schema/projects#getenv
https://atlasgo.io/hcl/functions#format

実用例

variable "mysql_user" {
  type    = string
  default = getenv("MYSQL_USER")
}

variable "mysql_password" {
  type    = string
  default = getenv("MYSQL_PASSWORD")
}

variable "db_host" {
  type    = string
  default = getenv("DB_HOST")
}

variable "db_port" {
  type    = string
  default = getenv("DB_PORT")
}

variable "mysql_database" {
  type    = string
  default = getenv("MYSQL_DATABASE")
}

env "gorm" {
  src = data.external_schema.gorm.url

  // マイグレーション適用先
  url = format(
    "mysql://%s:%s@%s:%s/%s?charset=utf8mb4&parseTime=true&loc=Local",
    var.mysql_user,
    urlescape(var.mysql_password),
    var.db_host,
    var.db_port,
    var.mysql_database,
  )

  // マイグレーションファイル生成に必要
  dev = format(
    "mysql://%s:%s@%s:%s/%s?charset=utf8mb4&parseTime=true&loc=Local",
    var.mysql_user,
    urlescape(var.mysql_password),
    var.db_host,
    var.db_port,
    "atlas",
  )
}

破壊的変更の制御

DROP系の変更を意図せず実行しないために、変数で制御できるようにしておくと安全です。

variable "destructive" {
  type    = bool
  default = false
}

env "gorm" {
  diff {
    skip {
      drop_schema = !var.destructive
      drop_table  = !var.destructive
    }
  }
}

コマンド

マイグレーションファイル生成

atlas migrate diff --config file://atlas.hcl --env gorm

マイグレーション適用

atlas migrate apply --config file://atlas.hcl --env gorm

DB全消し(schema clean)

接続先DBの全オブジェクト(全テーブル)が削除されます。開発環境またはローカル環境でのみ利用してください。

atlas schema clean --config file://atlas.hcl --env gorm

まとめ

AutoMigrateからAtlasへ移行すると、差分生成とバージョン管理が明確になり運用が楽になります。
まずはスタンドアローン構成で導入し、dev/urlの設定や破壊的変更の制御を整えると実務でも扱いやすくなります。
本番に進む場合はCIでのlintや適用フローの整理を検討すると安心です。
無料版の制約が厳しいように感じました。DB設計と照らし合わせて、どこまで自前で管理するのかも含め、検討する必要があります。

1
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
1
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?