本文へ移動
AI Dev Lab Japan AI開発ツール、AIコーディングエージェント、M...

CodexにDB migrationを任せる前に決めること

CodexにDB migrationを任せる前に決めることの要点をタイトルと確認軸で示すアイキャッチ

3行まとめ

Visualmigration前の4点本番前に分けます。
Expand

追加。

Backfill

補完。

Contract

削除。

Rollback

復旧。

DB migrationは、1つの差分ではなく段階を分けた運用です。

  • CodexにDB migrationを任せる時は、migration fileだけでなく、expand/contract、lock、backfill、deploy順序、rollback、ownerを先に決めます。
  • schema変更とdata変更を同じ差分へ詰め込むと、本番で戻しにくくなります。追加、両対応、補完、切替、削除へ段階化します。
  • PostgreSQLのALTER TABLEやPrisma Migrateのshadow database、schema driftの考え方を踏まえ、Codexには「書くSQL」だけでなく「確認する条件」も渡します。

CodexにDB migrationを頼むと、migration fileやORM schemaの差分はすぐ作れます。columnを追加する。名前を変える。NOT NULLを足す。indexを作る。古いcolumnを消す。小さな差分なら、PR上ではとても自然に見えます。

ただ、DB migrationはコード差分と違います。deploy後に本番データが変わります。長いlockが発生することがあります。backfillが途中で止まることがあります。rollbackしてもdataは戻らないことがあります。古いapp versionと新しいapp versionが同時に動く時間もあります。

この記事では、CodexにDB migrationを任せる前に、依頼文へ入れるべき条件を整理します。コード全体の移行は公開済みのCodexにコード移行を任せる前に決めることで扱いました。ここでは、schema変更とdata変更に絞ります。

この記事でわかること

Visual確認する材料Codexへ渡す前の整理です。
Lock

影響。

Data

変換。

Deploy

順序。

Owner

判断。

schema変更、data変更、deploy順序を分けるとreviewが楽になります。

  • DB migrationをCodexへ頼む前に決める7項目
  • expand/contractで破壊的変更を後ろへ送る考え方
  • PostgreSQLのALTER TABLEでlockやscanを気にする理由
  • Prisma Migrateのshadow database、schema driftをどう見るか
  • backfillをmigration fileのついでにしない設計
  • rollbackとroll-forwardを事前に分ける方法
  • Codexへそのまま渡せる依頼packet
  • reviewで止めるべきmigration差分

この記事は、特定DBの完全な運用手順ではありません。PostgreSQL、MySQL、SQLite、MongoDB、Prisma、Rails、Django、Flyway、Liquibaseなどで詳細は変わります。実際のSQL、lock、index作成、transaction、replication、backup、restoreは、利用中のDBとmigration toolの公式Docsで確認してください。

前提知識

Visual見る一次情報DBとtoolを分けます。
項目内容見方
PostgreSQLALTER。
Prismamigrate。
Shadow DBdrift。
Productiondeploy。

migrationはORMの機能だけでなく、DB側のlockやscanも見ます。

DB migrationは、source codeとdatabase stateの両方に影響します。PRで見えるのはmigration fileやschema fileですが、本番で起きるのはtable定義の変更、data変換、index作成、constraint検証、lock、replication遅延、application compatibilityです。

PostgreSQLのALTER TABLE Docsでは、subcommandごとに必要なlock levelが変わり、明示がない場合はACCESS EXCLUSIVE lockが取得されることが説明されています。また、SET NOT NULLでは既存行の確認が必要になる場合があります。Prisma Migrateでは、developmentでshadow databaseを使い、migration historyからschema driftやdata lossの可能性を検出する考え方が説明されています。

migrationはコード差分より戻しにくい

コードは前のversionへ戻せます。しかし、DBに入ったdata変更、dropしたcolumn、変換済み値、失敗途中のbackfillは、単純なgit revertでは戻りません。

そのため、Codexへは「migration fileを作って」ではなく、「どの順序で安全に変えるかを設計して」と頼みます。

dev commandとproduction commandを分ける

development用のcommandとproduction用のcommandを混同しないことも重要です。Prismaではmigrate devmigrate deploymigrate resetmigrate resolveのように用途が分かれています。developmentで便利なresetは、本番では破壊的です。

Codexへは、実行してよいcommand、実行してはいけないcommand、dry-runやdiffだけ許可するcommandを明示します。

migration前に決める7項目

Visual7つの決定差分前に決めます。
項目内容見方
Change変更。
Data変換。
Lock影響。
Backfill補完。
Deploy順序。
Rollback復旧。
Owner承認。

未定のままmigration fileを書くと、本番で判断することになります。

DB migrationを頼む前に、7項目を決めます。

項目決めること曖昧なまま起きること
変更add、rename、drop、constraint、index破壊的変更が混ざる
databackfill、変換、削除rollback不能になる
locktable lock、scan、rewrite本番trafficを止める
deployappとDBの順序古いappが壊れる
rollback戻すか進めるか障害時に迷う
verify件数、constraint、query成功判定が曖昧
owner承認者と実行者本番判断が宙に浮く

CodexはSQLやORM schemaを作れますが、本番の停止許容時間、backup方針、メンテナンス窓、replica、traffic量、障害時の判断者は知りません。ここは人間が渡す必要があります。

schema変更とdata変更を分ける

schema変更は、tableやcolumnやindexやconstraintを変える作業です。data変更は、既存行を埋める、値を変換する、重複を解消する、古い値を削除する作業です。

同じPRに入っていても、実行タイミングは分けます。schemaを先に足し、appを両対応にし、backfillし、確認してからconstraintやdropへ進みます。

ownerを決める

DB migrationにはownerが必要です。migration作成者、reviewer、実行者、障害時の判断者を分けます。Codexが作った差分でも、実行判断は人間が持ちます。

reviewで見ること

reviewでは、migration fileのSQLだけでなく、deploy順序、data影響、rollback/roll-forward、確認query、実行時間の見積もり、large tableの扱いを見ます。

expand/contractで小さく進める

Visual段階化の流れ追加してから切り替えます。
  1. 1Add

    追加。

  2. 2Dual

    両対応。

  3. 3Backfill

    補完。

  4. 4Switch

    切替。

  5. 5Drop

    削除。

破壊的変更を後ろへ送ると、deployとrollbackの余地が残ります。

DB migrationは、expand/contractで小さく進めると安全になります。

expand: 新しいcolumnやtableを追加する
dual: 古いschemaと新しいschemaの両方に対応する
backfill: 既存dataを新しいschemaへ補完する
switch: read/writeの参照先を切り替える
contract: 古いcolumnや古い処理を削除する

この流れにすると、古いapp versionと新しいapp versionが同時に動いても壊れにくくなります。

addから始める

最初は追加から始めます。新しいnullable column、新しいtable、新しいindex、新しいwrite pathなどです。既存のread/writeを壊さない変更なら、rollbackの余地が残ります。

removeは最後にする

drop column、rename、NOT NULL追加、constraint追加、古いfield削除は最後に回します。特にdropは戻しにくいです。使われていないことをログ、query、コード検索、feature flag、dashboardで確認してから行います。

評価基準

古いapp versionでも、新しいapp versionでも、migrationの途中状態で動くなら良い進め方です。途中状態を許容できないmigrationは、deploy窓や停止手順が必要です。

lockとtable rewriteを見る

Visual影響を見る場所本番DBの負荷です。
項目内容見方
Lock待ち。
Scan確認。
Rewrite書換。
Index作成。

migration reviewではSQLの見た目だけでなく、DBが何をするかを見ます。

DB migrationのreviewでは、SQLの見た目だけでなく、DBが何をするかを見ます。

PostgreSQLのALTER TABLEは、subcommandごとにlockやscanの影響が違います。SET NOT NULLでは既存行の確認が必要になる場合があります。column追加、default、constraint、index作成、type変更は、table sizeやDB versionによって影響が変わります。

ALTER TABLEの影響を読む

Codexへは、対象DBの公式Docsを読ませた上で、migrationごとに次を説明させます。

  • lockが強い操作か
  • table scanが必要か
  • table rewriteが起きる可能性があるか
  • transaction内で実行できるか
  • long-running queryやwrite trafficに影響するか
  • replicaやbackupに影響するか

large tableを別扱いにする

小さなtableなら一瞬で終わるmigrationでも、large tableでは長時間のlockやI/Oが発生することがあります。行数、サイズ、write頻度、index数、FK、trigger、replicationを見ます。

large tableでは、online migration、concurrent index、chunked backfill、maintenance window、traffic制御を検討します。

backfillをjobとして扱う

Visualbackfill運用長い処理を分けます。
  1. Plan

    範囲。

  2. Chunk

    分割。

  3. Run

    実行。

  4. Resume

    再開。

  5. Verify

    確認。

backfillはmigration fileのついでではなく、再開できるjobとして扱います。

backfillは、migration fileのついでに書くものではなく、jobとして扱います。

たとえば、新しいnormalized_email columnを追加する場合、既存user全件を更新する必要があります。これを1つのmigration transactionで全件更新すると、lock、WAL、replication、timeout、rollbackの問題が出ます。

chunkとresumeを入れる

backfillはchunkに分けます。ID範囲、created_at範囲、pagination、limitで分割し、途中で止まっても再開できるようにします。

1回のjobで最大1000件だけ更新する。
最後に処理したIDを記録する。
既に埋まっている行はskipする。
失敗時は同じchunkを再実行しても壊れない。

このような条件をCodexへ渡します。

進捗を記録する

backfillには進捗が必要です。対象件数、完了件数、残件数、失敗件数、再試行回数、処理時間、最後のerrorを記録します。

注意点

backfill中に新しいwriteが発生する場合、dual writeやread fallbackが必要になることがあります。migration単体で完結させず、app codeと一緒に設計します。

rollbackとroll-forwardを決める

Visual戻し方の判断schemaとdataを分けます。
  1. 1Stop

    停止。

  2. 2Assess

    判断。

  3. 3Rollback

    戻す。

  4. 4Forward

    進める。

  5. 5Verify

    確認。

dataを変えた後は、schema rollbackだけでは戻らないことがあります。

DB migrationでは、rollbackだけが正解とは限りません。dataが変わった後は、schemaだけ戻してもアプリが正しく動かないことがあります。

事前に、どの失敗ならrollbackするか、どの失敗ならroll-forwardするかを決めます。

状態対応理由
migration未実行deploy停止影響前
schema追加のみapp rollback可能追加は残せる
backfill途中job停止と再開dataは途中状態
constraint失敗data修正後に再実行原因がdata
drop後に障害backup/restore検討schema rollbackだけでは不足

schema rollbackだけで戻らない

drop column後にコードを戻しても、古いコードが読むcolumnはありません。data変換後に型を戻しても、元の値は失われているかもしれません。

そのため、破壊的変更は最後にし、backup、restore、roll-forward patch、feature flag、read fallbackを用意します。

deploy順序を固定する

DB migrationとapp deployの順序は固定します。

1. 新schemaを追加する
2. appを両対応にする
3. 新writeを有効にする
4. backfillする
5. readを切り替える
6. 古いschemaを削除する

Codexへは、この順序から外れる差分を作らないよう指示します。

Codexへ渡す依頼packet

Visual依頼packetそのまま渡せる型です。
項目内容見方
Goal目的。
SQL変更。
Risk影響。
Tests確認。
Ops運用。

packet化すると、Codexが書くmigrationと人間のreview観点が揃います。

Codexへは、次のようなpacketで渡します。

目的:
  users.email を正規化した normalized_email columnへ移行する。

DB:
  PostgreSQL。large tableのため、長時間lockを避ける。

許可する変更:
  nullable columnの追加。
  app codeのdual write。
  chunked backfill job。
  確認query。

禁止:
  既存columnのdrop。
  いきなりNOT NULLを付ける。
  migration transaction内の全件UPDATE。
  productionでreset系commandを実行する。

deploy順序:
  add column -> dual write -> backfill -> verify -> read switch -> NOT NULL検討 -> old path削除。

backfill:
  1000件ずつ処理する。
  再実行しても安全にする。
  進捗と失敗件数をlogへ残す。

review:
  lock、scan、rewrite、rollback、確認query、ownerをPR本文に書く。

このpacketがあると、Codexがmigration fileだけを作って終わることを避けられます。

よくある失敗

Visualbad patternsmigrationで崩れやすい点です。
Drop first

先に削除。

No backfill

未補完。

Long lock

長時間。

No owner

判断なし。

DB migrationの事故は、短いSQLの裏側にある運用未定義から起きます。

renameを1回で済ませる

column renameは、古いapp versionが残っていると壊れます。新column追加、dual write、read切替、古いcolumn削除に分けるほうが安全です。

NOT NULLを先に付ける

既存行にNULLがある状態でNOT NULLを付けると失敗します。先にbackfillし、確認queryでNULLがないことを見てからconstraintを追加します。

migration内で全件UPDATEする

全件UPDATEは、table size次第で長時間かかります。lock、WAL、replication、timeoutの影響があります。chunked jobへ分けます。

drop columnを同じPRで入れる

新しいschemaへ切り替えた直後に古いcolumnをdropすると、rollbackの余地がなくなります。観測期間を置き、古いpathが使われていないことを確認してから削除します。

driftを見ない

手動変更やbranch切替でmigration historyとDB schemaがズレることがあります。Prisma MigrateのDocsでは、shadow databaseを使ったdrift検出が説明されています。migration toolの警告を無視しないことが大事です。

FAQ

Visual判断の入口迷った時の見方です。
項目内容見方
Rename?段階。
NOT NULL?補完。
Drop?最後。
Rollback?事前。

迷ったら、古いコードと新しいコードが同時に動く時間を想像します。

Codexにmigration fileを書かせてもよいですか

書かせてもよいですが、実行判断は別です。Codexにはmigrationの意図、危険な操作、確認query、rollback/roll-forward条件を書かせ、人間がreviewします。

column renameはどう扱いますか

本番では、renameを1回で終わらせるより、新column追加、dual write、backfill、read切替、old column削除へ分けるほうが安全です。

rollback scriptも作るべきですか

作れる場合は作ります。ただし、data変換後は完全なrollbackができないことがあります。rollbackできる範囲とroll-forwardする条件を分けます。

Prismaのshadow databaseは本番にも必要ですか

PrismaのDocsでは、shadow databaseは主にdevelopmentでmigration historyからdriftやdata lossの可能性を検出するために使われ、本番向けcommandでは使われないことが説明されています。導入時は利用中のPrisma versionとcommandを確認してください。

migration reviewで最初に見るものは何ですか

drop、rename、NOT NULL、全件UPDATE、index作成、type変更、constraint追加、reset系commandを先に見ます。次にdeploy順序、backfill、rollback、確認query、ownerを見ます。

次に読むなら

参照した主な情報源

更新履歴

Visual更新メモ公開時点の整理です。
  1. 2026.06.01

    初版。

DBやORMのmigration仕様は変わるため、導入時に公式Docsを確認します。

  • 2026.06.01: 初版公開。CodexへDB migrationを任せる前のexpand/contract、lock、backfill、rollbackを整理しました。