データベースマイグレーション
任意の ORM とデータベースに適用可能な安全なスキーママイグレーションパターン。このスキルはマイグレーションの原則と安全パターンを定義するものであり、特定の ORM コマンドを定義するものではない。
設計原則
- プロジェクトのツールを発見: プロジェクトが使用する ORM/マイグレーションツールを検出
- コマンドをリサーチ: WebSearch で現在の ORM コマンド構文を調査
- 安全第一: ツールに関係なく安全なマイグレーションパターンに従う
- 常にロールバック可能に: 変更の取り消しを計画
マイグレーション安全チェックリスト
マイグレーション実行前:
- バックアップが存在するか復元可能
- マイグレーションが可逆(ダウンマイグレーション定義済み)
- データ損失リスクを特定済み
- 非本番環境でテスト済み
- スキーマドリフトを確認済み
ツール発見
ステップ 1: マイグレーションツールの検出
特定のツールを前提とせずにマイグレーション関連の設定を探す:
# マイグレーションディレクトリと設定を確認
ls -la migrations/ db/migrate/ alembic/ prisma/ drizzle/ 2>/dev/null
ls -la *migrate* *migration* *.prisma diesel.toml 2>/dev/null
# 依存関係でマイグレーションツールを確認
grep -E 'prisma|drizzle|alembic|django|sequelize|typeorm|knex|goose|diesel|flyway' \
package.json pyproject.toml requirements.txt go.mod Cargo.toml pom.xml 2>/dev/null
ステップ 2: プロジェクトコマンドを見つける
# マイグレーションスクリプトを確認
grep -E 'migrate|migration|db:' package.json 2>/dev/null
grep -E '^(migrate|db)' Makefile 2>/dev/null
ステップ 3: 現在のコマンドをリサーチ
ツールが検出されたがコマンドが不慣れな場合:
WebSearch: "[ORM/ツール名] migration commands [year]"
WebFetch: [公式ドキュメント] → "Extract migration CLI commands"
安全なマイグレーションパターン
これらのパターンは任意のデータベースとマイグレーションツールに適用:
カラムの追加
安全なアプローチ(NOT NULL の場合は 2 ステップ):
ステップ 1: nullable としてカラムを追加
ステップ 2: 必要に応じてデータをバックフィル
ステップ 3: NOT NULL 制約を追加(必要な場合)
理由: NOT NULL カラムを直接追加すると既存の行で失敗する。
カラムの削除
安全なアプローチ(3 ステップ):
ステップ 1: アプリケーションコードでカラムの使用を停止
ステップ 2: アプリケーション変更をデプロイ
ステップ 3: マイグレーションでカラムを削除
理由: コードが使用中のカラムを削除するとエラーが発生する。
カラムのリネーム
安全なアプローチ(4 ステップ):
ステップ 1: 新しいカラムを追加(旧のコピー)
ステップ 2: 旧から新にデータをコピー
ステップ 3: 新しいカラムを使用するようにコードを更新
ステップ 4: 旧カラムを削除
理由: 直接リネームするとデプロイ中に実行中のコードが壊れる。
インデックスの追加
安全なアプローチ:
- 小さなテーブル: 直接インデックス作成
- 大きなテーブル: コンカレント/オンラインインデックス作成を使用
理由: インデックス作成はテーブルをロックする。コンカレント作成はダウンタイムを回避。
注: コンカレントインデックスの構文はデータベースによって異なる - 特定のデータベースについてリサーチすること。
リスク評価
| 変更タイプ | リスクレベル | 軽減策 |
|---|---|---|
| nullable カラム追加 | 低 | 不要 |
| デフォルト値付きカラム追加 | 低 | デフォルト値を確認 |
| NOT NULL カラム追加 | 中 | まず nullable で追加、バックフィル、制約追加 |
| カラム削除 | 高 | コードが使用していないことを確認 |
| カラムリネーム | 高 | 追加/コピー/削除パターンを使用 |
| カラム型変更 | 高 | データ互換性をテスト |
| インデックス追加(小テーブル) | 低 | 不要 |
| インデックス追加(大テーブル) | 中 | コンカレント作成を使用 |
| インデックス削除 | 低 | クエリに不要であることを確認 |
ロールバック戦略
常にロールバックを計画する:
- 可逆マイグレーション: アップとダウンの両方のマイグレーションを定義
- ロールバックをテスト: デプロイ前にダウンマイグレーションが動作することを確認
- ロールバックスクリプトを保管: 必要に応じて手動ロールバック SQL を保存
- ロールバック手順を文書化: デプロイチェックリストに含める
ロールバックコマンド
マイグレーションツールのロールバックコマンドを発見する:
WebSearch: "[マイグレーションツール] rollback command"
本番チェックリスト
本番環境にマイグレーションをデプロイする前:
- ローカルでマイグレーションをテスト済み
- ステージング/プレビューでマイグレーションをテスト済み
- データベースバックアップを作成/確認済み
- ロールバック計画を文書化・テスト済み
- ダウンタイムウィンドウをスケジュール済み(必要な場合)
- チームにマイグレーションを通知済み
- 問題に対するモニタリング準備完了
- アプリケーションコードが旧スキーマと新スキーマの両方に互換性あり
よくある問題
スキーマドリフト
データベースがマイグレーションと異なる場合:
- 現在のスキーマと期待されるスキーマを比較
- 乖離した変更を特定
- いずれかを実施:
- 現在の状態に合わせるマイグレーションを生成
- マイグレーション状態にリセット(開発環境のみ)
マイグレーションの競合
複数のマイグレーションが競合する場合:
- 最新のマイグレーションを pull
- 順序の問題を確認
- マイグレーションファイルの競合を解決
- マイグレーションを再実行
失敗したマイグレーション
マイグレーションが途中で失敗した場合:
- 何が適用されたかを確認
- 部分的な変更を手動で修正またはロールバック
- マイグレーションを修正して再試行
- マイグレーションを解決済みとしてマーク(ツール固有)
Rules (L1 - Hard)
データの安全性に不可欠。違反はデータ損失を引き起こす可能性。
- ALWAYS: マイグレーション前にバックアップ(リカバリ要件)
- NEVER: 明示的な確認なしに破壊的マイグレーションを実行しない
- NEVER: 本番環境で reset/drop コマンドを実行しない
- NEVER: マイグレーションが自動的に可逆であると仮定しない
Defaults (L2 - Soft)
安全な操作に重要。適切な理由がある場合はオーバーライド可。
- まず非本番環境でマイグレーションをテスト
- ロールバック計画を文書化
- コマンド実行前にプロジェクトのマイグレーションツールを発見
- WebSearch で現在のコマンド構文を確認
- ORM 固有のコマンドをハードコードしない(発見する)
Guidelines (L3)
堅牢なマイグレーション実践のための推奨事項。
- consider: カラムリネームには追加/コピー/削除パターンの使用を検討
- prefer: 大きなテーブルにはコンカレントインデックス作成を推奨
- consider: マイグレーション前のスキーマドリフトチェックを検討
