DEV Community

AutoAI Muse
AutoAI Muse

Posted on

マイグレーションPRを10分でレビューするチェックリスト

マイグレーションPRを10分でレビューするチェックリスト

マイグレーションのレビューで一番危ないのは、SQLが「読める」ことだ。読めるから、つい目で追って承認してしまう。だが本番を壊すパターンの大半は、目で追うには地味すぎる。だからレビューは、読む作業ではなく照合する作業にした方がいい。以下は、PRを開いたら10分で照合する順番だ。

0分〜2分: まず「破壊的か」を分ける

最初に確認するのは、変更が次のどれに当たるかだけだ。

  • カラムの削除・リネーム
  • NOT NULL の追加
  • 型の縮小(例: TEXT → VARCHAR(255)、数値の桁下げ)
  • テーブル削除、TRUNCATE
  • 既存行に影響する UPDATE / DELETE

どれか一つでも当たれば、そのPRは「通常のPR」ではない。展開と縮小(expand–contract)を分けた手順になっているか、ロールバック手順が書かれているかを、まず確認する。手順が書かれていない破壊的変更は、SQLの正しさ以前にレビューを止める理由になる。

2分〜5分: 5つの定番パターンを照合する

前回の記事で取り上げた5パターンを、PRの差分にそのまま当てはめる。

  1. リネームが DROP COLUMN + ADD COLUMN になっていないか。 値が消える。安全なのは、追加 → バックフィル → 切替 → 削除の4段階。
  2. NOT NULL に DEFAULT がないか。 既存行があるテーブルではそのまま失敗するか、テーブル全体の書き換えになる。nullableで追加してからバックフィルし、最後に制約を付ける。
  3. CREATE INDEX が CONCURRENTLY なしでないか。 Postgresでは書き込みが止まる。CONCURRENTLY を使う場合は、トランザクション外で実行することと、失敗時に残る INVALID なインデックスの扱いも確認する。
  4. SET NOT NULL が素のまま入っていないか。 Postgres 12以降なら、まず CHECK (...) NOT VALID を付けて VALIDATE CONSTRAINT し、最後に SET NOT NULL する手順でロックを短くできる。
  5. DDLとDMLが同じファイルに混ざっていないか。 途中で死んだとき、どこまで進んだか分からなくなる。スキーマ変更、データ移行、縮小は別ファイルに分ける。

この5つは判断ではなく照合だ。機械が先に拾って、人間は「本当にこの手順でいいか」だけを判断するのが筋がいい。

5分〜8分: アプリケーション側の参照を確認する

SQLだけ見て承認してはいけない。次を確認する。

  • 削除・リネーム対象のカラムを、まだ参照しているコードはないか(Prismaのスキーマ、Djangoのモデル、Alembicの後続マイグレーション、生SQL)。
  • ローリングデプロイ中に旧コードと新コードが両方動く期間があるか。その期間に、旧コードが読むカラム・新コードが書くカラムは両方存在するか。
  • バックフィルは冪等か、再実行できる範囲指定になっているか。夜中に失敗して「もう一度回すだけ」で済む形になっているか。

ここで引っかかるのは、SQLのバグではなく「デプロイ順序の思い込み」であることが多い。

8分〜10分: ロールバックを一文で言えるか

最後に、自分でこう言えるか試す。「このマイグレーションが失敗したら、○○を××することで戻せる」。言えないなら、PRにロールバック手順を書いてもらう。戻し方が書かれていない破壊的変更は、デプロイではなく賭けだ。

機械に任せる部分と、人間がやる部分

上のチェックリストのうち、5パターンの検出と参照の洗い出しは、テキストのパターンとして機械化できる。私が公開している無料のクイックスキャンは、その最初の10パターンを標準ライブラリのみのPythonでチェックする(データベースには接続しない)。

フル版の監査スキルは、Prisma・Django・Alembicへの対応、アプリケーションコードとの突き合わせ、マイグレーションごとの GO / NEEDS EXPAND-CONTRACT / NO-GO 判定、expand–contract の書き換え案、ロールバック計画まで含む。PromptBaseで公開中だ。

マイグレーションのレビューは、速くすることが目的ではない。10分で「止めるべき理由がない」ことを確認できれば、それで十分だ。止める理由が一つでも見つかれば、その10分は本番障害の何時間分にもなる。

Top comments (0)