運用中のDBに後付け Prisma Migrate を途中から導入する実践ガイド
運用中のDBに後付け Prisma Migrate を途中から導入する実践ガイド(ハマりどころ解説付き)
はじめに (きっかけ)
「このプロジェクト、最初は Prisma 使ってたけど、マイグレーションまでは管理してなかったんだよな...」
「開発も進んで、そろそろちゃんとスキーマ変更を管理したいけど、_prisma_migrations
テーブルがない...」
そんな状況、ありませんか? 私もまさにその状況に直面しました。Prisma は導入済みでデータベーススキーマも存在しているけれど、Prisma Migrate によるマイグレーション管理は行われていない。運用が始まっているシステムだと、気軽に db push
するわけにもいきません。
この記事では、そんな状況から Prisma Migrate を後付けで導入しようとして、実際に私が経験した試行錯誤やハマりどころを踏まえつつ、具体的な手順と注意点を解説します。
前提条件
この記事は、以下の状況を想定しています。
- Node.js と npm/yarn/pnpm がインストールされている。
- プロジェクトに Prisma CLI と Prisma Client が導入済み。(Prisma 3 以降を想定)
- マイグレーション管理されていない既存のデータベースとスキーマが存在する。
- 最終的に
prisma migrate dev
やprisma migrate deploy
を使ってスキーマ変更を管理したい。
schema.prisma
の整備と配置場所
準備: 超重要! 途中から Prisma Migrate を導入する上で、最も重要と言っても過言ではないのが、schema.prisma
ファイルの準備とその配置場所です。
結論から言うと、schema.prisma
はプロジェクトルート直下の prisma
ディレクトリに配置してください。 これが Prisma の標準的な規約であり、後述する多くのトラブルを回避する鍵になります。
具体的な手順は以下の通りです。
-
prisma
ディレクトリの作成:
プロジェクトルートにprisma
ディレクトリがなければ作成します。mkdir prisma
-
schema.prisma
の移動:
もしschema.prisma
がプロジェクトルートなど、prisma
ディレクトリ以外の場所にある場合は、prisma
ディレクトリの中に移動させます。# 例: ルートにある schema.prisma を移動する場合 mv schema.prisma prisma/
-
schema.prisma
と DB スキーマの同期:
prisma/schema.prisma
の内容を、現在のデータベーススキーマの構造と一致させる必要があります。これには主に2つの方法があります。-
prisma db pull
を使う (推奨):
現在のデータベーススキーマを元にschema.prisma
を自動生成(または上書き)します。これが最も簡単で確実です。npx prisma db pull
注意: このコマンドは
prisma/schema.prisma
をデータベースの内容で完全に上書きします。手動で追記したコメントやカスタム設定などがある場合は、実行前にバックアップを取るか、実行後に再度追記してください。 -
手動で編集する:
既存のprisma/schema.prisma
を直接編集し、現在のデータベーススキーマと完全に一致するように修正します。テーブル定義、カラム定義、リレーションなどを正確に記述する必要があります。
-
これで、Prisma Migrate を導入する準備が整いました。prisma/schema.prisma
が最新のDB状態を反映しているはずです。
resolve --applied
を使用)
導入方法: ベースラインの設定 (Prisma 3 以降では、既存のデータベーススキーマを Prisma Migrate の管理下に置く(ベースラインを設定する)ために prisma migrate resolve
コマンドを使用します。
(注記) Prisma 2.x 系には prisma migrate baseline
という専用コマンドがありましたが、Prisma 3 以降では非推奨となり、resolve
コマンドに機能が統合されました。
手順:
-
ベースライン用マイグレーションディレクトリ作成:
最初のマイグレーションファイル(実際には空のスキーマからの差分を記録するもの)を格納するディレクトリを作成します。名前は公式ドキュメントに合わせて0_init
とするか、混乱を避けるためにタイムスタンプ付きの名前にしても良いでしょう(例:20250407000000_init
)。ここでは0_init
を使います。mkdir -p prisma/migrations/0_init
-
(任意だが推奨) 空スキーマからの差分 SQL 生成 (記録用):
現在のschema.prisma
の状態を表現する SQL を生成し、migration.sql
として保存します。これは実際にデータベースに適用するためのものではなく、あくまで「この状態がベースラインである」という記録のためです。npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
注意: 必ず
--from-empty
を付け、--to-schema-datamodel
で正しいprisma/schema.prisma
のパスを指定してください。 -
マイグレーションを「適用済み」としてマーク:
作成した0_init
マイグレーションが、あたかも既にデータベースに適用されたかのように Prisma に認識させるため、以下のコマンドを実行します。npx prisma migrate resolve --applied 0_init
これにより、
_prisma_migrations
テーブルが(なければ)作成され、0_init
が適用済みとして記録されます。
これで、既存のデータベーススキーマが Prisma Migrate の管理下に置かれました。
ハマりどころとトラブルシューティング
さて、ここからは私が実際にハマった点や、その解決策について共有します。これらの多くは schema.prisma
の配置場所が原因でした。
schema.prisma
の場所が prisma/
ディレクトリじゃない場合
1. 最初に試したとき、schema.prisma
をプロジェクトルートに置いたまま進めようとして、以下の問題に遭遇しました。
-
prisma migrate diff
でのエラー:
--to-schema-datamodel ./schema.prisma
のように指定しても、Error: Could not load ... file or directory not found
というエラーが発生しました。これは Prisma CLI が規約通りprisma/schema.prisma
を期待しているためと考えられます。prisma/
ディレクトリに移動し、パスをprisma/schema.prisma
に修正することで解決しました。 -
prisma migrate resolve
でのP3017
エラー:
schema.prisma
をルートに置いたまま、--schema ./schema.prisma
オプションを使ってresolve
を試みたところ、以下のエラーが発生しました。$ npx prisma migrate resolve --schema ./schema.prisma --applied 0_init Environment variables loaded from .env Prisma schema loaded from schema.prisma # スキーマは読み込めているが... Datasource "db": PostgreSQL database "geake", schema "public" at "localhost:5432" Error: P3017 # ↓ エラー発生! The migration 0_init could not be found. ...
--schema
オプションでスキーマファイルの場所は指定できているにも関わらず、resolve
コマンドがprisma/migrations/0_init
ディレクトリを見つけられないという状況でした。原因の推測と結論: Prisma CLI は、たとえ
--schema
でスキーマの場所を指定されても、マイグレーションディレクトリの探索など、内部的な処理においてprisma/
ディレクトリ構造という**「規約」**に強く依存している可能性が高いです。標準的でない場所にschema.prisma
があると、この規約から外れるため、0_init
のようなマイグレーション名を正しく解決できないようです。
対策はただ一つ、schema.prisma
はprisma/
ディレクトリに置くしかないっぽい😇
prisma migrate resolve
での P3017
エラー (再訪)
2. schema.prisma
の場所が適切でも、P3017
エラーが出る可能性はあります。
-
マイグレーション名の指定ミス:
--applied
に指定する名前は、prisma/migrations
ディレクトリ内に実際に存在するディレクトリ名と完全に一致させる必要があります。ls prisma/migrations
で確認し、0_init
なのか、あるいは<timestamp>_<name>
形式の名前なのかを正確に指定してください。# ls prisma/migrations で確認した名前を指定する npx prisma migrate resolve --applied <実際のディレクトリ名>
-
0_init
の扱い: 私の経験では、schema.prisma
がprisma/
ディレクトリにあれば、resolve --applied 0_init
は問題なく動作しました。しかし、--schema
オプションを使った場合は失敗した経緯もあり、ツールの挙動がパスの状況によって変わる可能性は否定できません。規約に従うのが最も安全です。
導入後の確認
resolve
コマンドが成功したら、以下の点を確認しましょう。
-
_prisma_migrations
テーブルの存在: データベース内にこのテーブルが作成されているか確認します。-- 例: PostgreSQL の場合 \dt _prisma_migrations; SELECT * FROM _prisma_migrations;
-
prisma migrate status
コマンド: このコマンドで、Prisma がデータベースのマイグレーション状態をどのように認識しているか確認できます。ベースライン (0_init
など) が適用済み (Applied) になっていれば OK です。
npx prisma migrate status
-
これで、Prisma Migrate の管理下にデータベースを置くことができました! 今後は以下のように運用できます。
-
スキーマ変更:
prisma/schema.prisma
を編集します。 -
マイグレーション作成と開発 DB への適用:
npx prisma migrate dev --name <migration_description>
を実行します。 -
本番環境などへの適用:
npx prisma migrate deploy
を実行します。
まとめ
運用中のシステムに後から Prisma Migrate を導入するのは、いくつかのポイントを押さえれば十分に可能です。
-
prisma migrate resolve --applied <baseline_migration_name>
を使ってベースラインを設定するのが現在の標準的な方法です。 -
最重要:
schema.prisma
は必ずprisma/
ディレクトリに配置する! これだけで多くの問題を回避できます。 -
resolve
コマンドで指定するマイグレーション名は、実際に存在するディレクトリ名と一致させる。 - ハマりどころを知っておけば、スムーズに導入を進められます。
この記事が、同じような状況で困っている方の助けになれば幸いです。
Discussion
resolve
は上記に該当しないので、機能してないのかもしれないです🤔resolve
のリファレンスには--schema
ありますけど、、😅本当ですね・・・。
完全に罠と化してる状態かもです。
それか、0_initみたいなフォルダ名のときだけとか?なのかなって今更思ったりしました。