はじめに
この記事で扱う範囲は、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設計と照らし合わせて、どこまで自前で管理するのかも含め、検討する必要があります。