🐈
Entity Framework Coreのマイグレーションを安全に運用するための設計と工夫
Entity Framework Coreのマイグレーションを安全に運用するための設計と工夫
✅ はじめに
Entity Framework Core(EF Core)のマイグレーション機能は、コードベースでDBスキーマを管理できる便利な仕組みですが、運用を誤ると本番DBの破壊やチーム内の混乱を招きます。この記事では、実際の運用を想定して、EF Coreマイグレーションを安全・確実に運用するための設計と工夫を紹介します。
💣 よくあるマイグレーション事故パターン
dotnet ef database update
が直撃
1. 本番に- 本番環境でうっかりCLIを実行し、想定外のスキーマ変更が反映される
- 対応:本番ではSQLをレビューしてから適用を徹底
2. 開発者ごとのスキーマ差異
- 開発環境のDB構成がバラバラで、マイグレーションに齟齬が出る
- 対応:明示的なローカル初期化とマイグレーション適用フローの整備
3. マージでマイグレーションが衝突
- 同時期に複数人がマイグレーションを追加し、順序が競合
- 対応:マイグレーション命名とPR内レビューの徹底
🧱 設計とルールで防ぐ
1. 命名規則
20240517_AddUserStatusColumn.cs
- 作成日+機能内容で命名(競合しにくく、変更履歴も把握しやすい)
2. ステージングでの差分確認
-
dotnet ef migrations script
で生成したSQLをステージングDBに適用し、影響範囲を確認
3. マイグレーションのレビュー文化
- PRで必ずマイグレーションSQLをコメントとして貼付
- ex.
dotnet ef migrations script 20240510 20240517
4. 本番ではマイグレーションSQLを明示適用
- CIで出力されたSQLを手動またはスクリプトで適用
-
DbContext.Database.Migrate()
は本番では使用禁止(開発・テスト用)
🛠️ CI/CDパイプラインの工夫
パイプライン上での基本的な流れ
- マイグレーションファイルが追加されたことを検出
-
dotnet ef migrations script
で差分SQLを生成 - 差分SQLを成果物(artifact)として保存
- Pull RequestにSQLを自動コメント
- (任意)ステージング環境に自動適用して検証
🔄 自動でマイグレーション範囲を検出する方法
EF Coreの dotnet ef migrations script
は、以下のように 開始マイグレーション名と終了マイグレーション名 を指定できます:
# 差分のSQLを生成
# 例:20240510 から 20240517 の差分を出力
dotnet ef migrations script 20240510 20240517 --output migration.sql
しかし、これを毎回手動で書くのは面倒です。CI上では次のように自動で最後に適用されたマイグレーションと最新のマイグレーションを検出し、その範囲を用いてスクリプトを生成する運用が有効です。
__EFMigrationsHistory の活用
EF Core では、マイグレーションの適用履歴を自動的に追跡するためのテーブル __EFMigrationsHistory
が作成されます。このテーブルには、過去に適用されたマイグレーションの一覧が格納されており、前回適用済みのマイグレーション名を正確に取得することができます。
__EFMigrationsHistory
の構造(例)
MigrationId | ProductVersion |
---|---|
20240510_AddEmailToUsers | 8.0.4 |
20240517_AddStatusToUsers | 8.0.4 |
利用方法(SQL)
SELECT MigrationId
FROM __EFMigrationsHistory
ORDER BY MigrationId DESC
LIMIT 1;
CI/CD パイプラインでこの情報を DB から取得し、dotnet ef migrations script
の fromMigration
として使うことができます。
スクリプト例(psql を使った取得)
# PostgreSQL例
export FROM_MIGRATION=$(psql "$CONNECTION_STRING" -t -c "SELECT MigrationId FROM __EFMigrationsHistory ORDER BY MigrationId DESC LIMIT 1;" | xargs)
export TO_MIGRATION=$(dotnet ef migrations list | grep '^[[:space:]]*[0-9]' | tail -n 1 | xargs)
dotnet ef migrations script $FROM_MIGRATION $TO_MIGRATION --output ./artifacts/migration.sql
運用上の利点
-
previous_migration.txt
の手動更新不要 - 本番DBの実際の状態に基づいてスクリプトを生成
- 適用漏れやずれを防げる
✅
__EFMigrationsHistory
はすべての EF Core プロジェクトで自動生成され、マイグレーションの正確なトラッキングに利用可能です。
GitHub Actionsで更新する例(mainマージ時)
GitHub Actions の例
- name: Generate SQL script from EF Core
run: |
from=$(sqlcmd -S your-sqlserver -d your-db -U your-user -P your-password -Q "SET NOCOUNT ON; SELECT TOP 1 [MigrationId] FROM [__EFMigrationsHistory] ORDER BY [MigrationId] DESC" -h -1 -W)
to=$(dotnet ef migrations list | grep '^[[:space:]]*[0-9]' | tail -n 1 | xargs)
dotnet ef migrations script $from $to --output ./artifacts/migration.sql
PRへの自動コメント例
PRコメントに以下のように表示:
### 🔍 EFマイグレーション差分SQL
```sql
ALTER TABLE Users ADD COLUMN Status INT NOT NULL DEFAULT 0;
...
### ステージング検証の組み込み(オプション)
- ステージングDBに対して差分SQLを適用
- 結果に応じてSlack通知やGitHubチェックを返す
### 本番環境への反映
- 出力された `migration.sql` をレビュー・承認後に、DBAまたはデプロイスクリプトで手動適用
- 適用ログは必ず保存して監査対応にも備える
## 🧪 テスト環境でのリハーサル
### ローカルでの検証手順
```bash
# 一度DBを削除
dotnet ef database drop -f
# 最新マイグレーションを適用
dotnet ef database update
- すべてのマイグレーションが連続して正しく適用できることを保証
自動検証
- CIで空のSQLite DBにマイグレーション適用して検証
- 実スキーマとの差分を検出するツール導入(EF Power Tools など)
🧭 応用Tips
マイグレーションのマージ
- 衝突時は
Remove-Migration
+Add-Migration
で統合 - Gitのリベースと一緒に調整することできれいな履歴に
モデルの変更検知
- 差分があるのにマイグレーションを忘れた場合、CIで警告を出す
- 例:
dotnet ef migrations add DummyCheck
で差分検知用のダミーを作る
📚 まとめ
- EF Coreのマイグレーションは便利だが、運用設計が命
- 本番では自動適用せず、SQLレビューと手動適用を原則とする
- チーム内のルールと自動化によって、事故を防ぎつつ効率的に運用可能
Discussion