![見出し画像](https://assets.st-note.com/production/uploads/images/113462195/rectangle_large_type_2_41556be69222b2bee7e66f9357e8cc06.png?width=1200)
難しいMigrationのハナシ
なぜMigrationか
エンジニアになりたてのころ、Migrationと聞いて「なんぞそれ」と思って検索したものの何かしっくりくる答えが得られなかった。今までなんと無くのニュアンスでやってきたが、そろそろちゃんとまとめようと思った。
つまりここの難しいって言うのは、「Migrationの専門的なお話」ではなく、当時の私にとって(多分今も)「難しくてよく分からんMigrationのメモ」的なニュアンス。
ということで聞いてみた
ググっても良い感じの答えに辿り着けなかった経験から、AIさんに聞いてみた。今はやりの(?)ChatGPTさんによるとこんな感じ
データベースのマイグレーション(Migration)は、ソフトウェア開発においてデータベースのスキーマ(データベースの構造やテーブル、カラム、インデックスなどの定義)を変更するプロセスです。新しい機能の追加、既存の構造の変更、データモデルの最適化などがその例です。
つまり、わざわざDBに接続してALTER TABLE〜!!とかしなくてもいい。develop, staging, productionとかで環境を分けている場合も、それぞれにSQL叩いて変更を適用して・・・みたいな超ミスりそうな作業をしなくてもいい。Migrationファイルを一発適用してやれば、テーブル追加もカラム変更もサクゥッっとできる!
じゃあ、実際Migrationってどうやってやるか。ざっくり記載すると以下のようになる。
1. Migrationファイルを作る
2. 作ったMigrationファイルをDBに適用する
3. データの型が変わる場合は変換処理を入れる
これから実際にMigrationファイルを作っていく。
go-migrate
migrationには以下のgo-migrationを使う。今回の実装言語はGolang。
https://github.com/golang-migrate/migrate
まずはpostgresにデータベースを作る。
CREATE DATABASE temp_db;
次に、migrateコマンドを打って実際に使うMigrationファイルを生成。
// このコマンドでmigrationsディレクトリ配下にファイルが作られる
$ migrate create -ext sql -dir migrations/hoge -seq create_tmp_table
生成されたファイルの中身は空なので、ここに自分でSQLを書いていく。末尾にupとついたファイルは作成用、downと付いているのは切り戻し用のファイル。
-- 000001_create_tmp_table.up.sql
CREATE TABLE IF NOT EXISTS tmp(
id uuid NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(),
name varchar(255) NOT NULL
);
-- 000001_create_tmp_table.down.sql
drop table tmp;
いざ、Migration!!
migrateコマンドを叩いてMigrationを実行。なお、userとpassはご自分で設定したものを入れてください。
$ export POSTGRESQL_URL='postgres://user:pass@0.0.0.0:5432/temp_db?sslmode=disable'
$ migrate -database 'postgres://user:pass@0.0.0.0:5432/temp_db?sslmode=disable' -path migrations/hoge up
⚠️⚠️⚠️エラー⚠️⚠️⚠️
もしSQL文にエラーがあった場合、Migrationは失敗します。この時、上のSQLで指定したデータベースに自動でscheme_migrationsというテーブルが作成されます。ここでMigrationのステータスやバージョンが管理されています。
今はエラーでMigrationが失敗しましたが、その場合もscheme_migrationsのバージョンは上がってしまいます。この状態でMigrationを行うと、たとえ正しいSQLに書き換えていても以下のようなエラーになります。
error: Dirty database version 1. Fix and force version.
普段ならscheme_migrationsテーブルのバージョンを一つ前に戻してあげればいいのですが・・・初回だけはバージョンが0になってしまうこともあり上手くいきませんでした。なのでscheme_migrationsテーブルをdropして、再度Migrationをかけます。そうすると、以下のように成功したとメッセージが表示されます!!!
1/u create_tmp_table (49.269375ms)
まとめ
Migrationって便利だね
でもバージョン管理でコケるとちょっと面倒だね
特に初回はdirty database versionで怒られがちなので落ち着いて対処しようね
困ったら自動で作られるscheme_migrationsテーブルをのぞいてみようね
参考にさせていただいたサイト
https://dev.classmethod.jp/articles/db-migrate-with-golang-migrate/
免責事項: この記事の内容は執筆時点での情報に基づいています(2023年8月)。OpenAIのChatGPTに関する最新情報やポリシーについては、OpenAI公式ウェブサイトや公式情報源をご確認ください。本記事に記載された情報が変更された場合、それに関する最新の情報を提供するために努力いたしますが、正確性を保証するものではありません。
この記事が気に入ったらサポートをしてみませんか?