Prisma × Claude Code:スキーマ設計からマイグレーションまでAIで自動化する
TL;DR
- Claude Codeはスキーマ生成・マイグレーション草案に使えるが、「設計意図」の事前共有が品質を左右する
- CLAUDE.mdにDB設計方針を書くと、Claude Codeの生成品質が大幅に安定する
migrate devとdb pushの使い分けはAIに任せず人間が判断すること- Prisma v7からは
prisma generateの自動実行が廃止。スキーマ変更後は明示的な実行が必要 - 本番DBへの
migrate deploy実行判断は必ず人間が行う
Prismaを使うバックエンド開発では、スキーマの変更が頻繁に発生する。新機能追加のたびにmodelを追加し、リレーションを定義し、マイグレーションファイルを生成する一連の作業は、カラム名のタイポや @relation の記述ミスなど小さなエラーの温床になりやすい。
Claude Codeはこの繰り返し作業を大幅に省力化できる。しかし「AIにスキーマを書かせたら意図と違う構造が出てきた」という経験をしたことはないだろうか。本記事では、その原因と解決策を具体的なプロンプト例・before/after形式で解説する。
Claude Codeの導入・セットアップがまだの場合は、まずClaude Code導入・セットアップ(2026年版)を参照してほしい。
なぜPrisma × Claude Codeなのか
Prismaが自動化に向いている理由
Prismaのアーキテクチャは「スキーマファースト」という設計思想を持つ。schema.prisma という単一ファイルにデータモデルを宣言的に記述し、そこからTypeScript型・クライアントコード・マイグレーションSQLをすべて生成する構造だ。
この構造はClaude Codeとの相性が非常に良い。理由は3つある。
1. 入出力が明確なテキストファイル
schema.prisma はシンプルなテキスト形式で、構文ルールが厳格に定義されている。Claude Codeは既存のスキーマを読み込んで差分を追加するという作業を正確にこなせる。
2. 型安全性の恩恵をそのまま受けられる
Claude Codeが生成したスキーマから prisma generate でPrisma Clientを生成すると、TypeScriptの型チェックが自動的に走る。AIの出力ミスをコンパイラが検知してくれるため、ランタイムエラーのリスクが下がる。
3. 変更の単位が小さく、差分が追いやすい
モデルの追加・カラムの変更・インデックスの追加などの操作は、スキーマファイル内の局所的な変更に対応する。Claude Codeに「ここを変えて」と指示しやすく、レビューも容易だ。
Claude CodeがPrismaタスクで特に役立つ3つの場面
場面1:新規モデルの追加
要件をテキストで伝えると、model 定義・@relation フィールド・インデックス設定までまとめて出力してくれる。
場面2:既存モデルのリファクタリング
「User モデルに profile を1対1リレーションで追加して」という指示で、既存のフィールドを壊さずに差分だけを生成できる。
場面3:Prisma Clientクエリの生成
findMany の条件絞り込み・include による関連モデルの結合取得など、型安全なクエリを即座に書いてくれる。
スキーマ設計をClaude Codeに任せる
基本プロンプトパターン(要件→スキーマへの変換)
Claude Codeへの指示は「要件(何を実現したいか)」と「制約(既存の構造・命名規則)」をセットで伝えることが基本だ。
# 要件
ECサイトの注文管理機能を追加したい。
# 制約
- 既存の User モデル(id: String @id @default(cuid()))に紐づける
- テーブル名はスネークケース(@map)で定義する
- 全テーブルに createdAt / updatedAt を付ける
- PostgreSQL を使用している
# 作成してほしいモデル
- Product(商品): 名前、価格、在庫数
- Order(注文): ユーザーとの関係、注文日時、合計金額、ステータス
- OrderItem(注文明細): 注文と商品の中間テーブル、数量、単価
要件と制約を明示することで、Claude Codeは既存の構造を壊さずに追加スキーマを生成できる。
プロンプト実例:ECサイトの商品・注文モデル設計(before/after)
Before(曖昧な指示):
ECサイトの商品・注文テーブルをPrismaで作って
このような指示では、命名規則・型の選択・リレーション設計がすべてClaude Codeの「推測」に委ねられる。IDの型が Int か String か、cuid() か uuid() かすら指定されないため、既存テーブルと不整合が起きやすい。
After(具体的な指示):
以下の要件でPrismaスキーマにモデルを追加してください。
## 既存スキーマ(抜粋)
model User {
id String @id @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("users")
}
## 追加要件
- Product: 商品名(String)、説明(String? @db.Text)、価格(Int、円単位)、在庫数(Int)
- Order: Userとの多対1、注文日時(DateTime)、合計金額(Int)、ステータス(Enum: PENDING/PAID/SHIPPED/CANCELLED)
- OrderItem: OrderとProductの中間テーブル、数量(Int)、注文時単価(Int)
## 制約
- @id は全て cuid()
- テーブル名は @@map でスネークケースを指定
- createdAt/updatedAt を全モデルに付与
- DB は PostgreSQL
出力例:
enum OrderStatus {
PENDING
PAID
SHIPPED
CANCELLED
}
model Product {
id String @id @default(cuid())
name String
description String? @db.Text
price Int
stock Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
orderItems OrderItem[]
@@map("products")
}
// User モデルに追記(双方向リレーションが無いと prisma validate が失敗する)
model User {
// ...既存フィールドは省略
orders Order[]
}
model Order {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id])
status OrderStatus @default(PENDING)
totalAmount Int
orderedAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
items OrderItem[]
@@map("orders")
}
model OrderItem {
id String @id @default(cuid())
orderId String
order Order @relation(fields: [orderId], references: [id])
productId String
product Product @relation(fields: [productId], references: [id])
quantity Int
unitPrice Int
createdAt DateTime @default(now())
// updatedAt は注文明細の不変性を考慮し意図的に省略
// 変更可能フィールドが増える場合は追加すること
@@map("order_items")
}
出力されたスキーマは prisma format で整形し、型・リレーション方向・@@map の命名を目視で確認してからコミットする。
CLAUDE.mdにPrismaの設計意図を書く方法
Claude Codeの生成品質を安定させる最大のポイントは、セッションをまたいで設計意図を保持させることだ。毎回プロンプトに制約を書き直すのは非効率で、書き忘れリスクもある。
CLAUDE.mdにPrismaの設計方針を明文化することで、Claude Codeは常にそのコンテキストをベースに動作する。詳細な記述パターンはCLAUDE.md設計ガイドで解説しているが、Prisma向けの最小テンプレートは以下の通りだ。
## Prismaスキーマ設計方針
### 基本ルール
- DB: PostgreSQL 16
- Prismaバージョン: v7.x(prisma generate は migrate dev/db push 後に手動実行が必要)
- ID: すべて `String @id @default(cuid())`
- テーブル名: `@@map` でスネークケースを指定
- タイムスタンプ: 全モデルに `createdAt DateTime @default(now())` と `updatedAt DateTime @updatedAt` を付与
### 命名規則
- モデル名: PascalCase(例: UserProfile)
- フィールド名: camelCase(例: firstName)
- Enum値: UPPER_SNAKE_CASE(例: `PENDING` / `SHIPPED`。enum名自体は PascalCase の `OrderStatus`)
### リレーション設計
- 外部キーフィールドは `{モデル名}Id` の形式(例: userId)
- 双方向リレーションを明示的に定義する
- 削除時の挙動(onDelete)はモデルごとに明示する
### 禁止事項
- prisma migrate dev / db push コマンドを Claude Code が直接実行しないこと
- 本番環境への prisma migrate deploy を AI 判断で実行しないこと
### マイグレーション
- 開発中のスキーマ実験: db push を使用
- 正式なマイグレーションファイル生成: migrate dev を使用
- 本番適用: migrate deploy(人間が手動でレビュー・実行)
このテンプレートをプロジェクトのCLAUDE.mdに追記することで、Claude Codeは毎回この方針に従ってスキーマを生成するようになる。
マイグレーション生成と検証
Claude Codeにマイグレーション草案を書かせる手順
Claude Codeはマイグレーションの意図の説明とスキーマ変更の草案を生成するのが得意だ。ただし、実際のSQLマイグレーションファイルは prisma migrate dev が自動生成するため、Claude CodeにSQLを直接書かせる必要はない。
効果的な活用手順は以下の通り:
-
Claude Codeにスキーマ変更を書かせる
「既存の User モデルに phoneNumber フィールドを追加して」と指示し、schema.prismaの差分を受け取る -
差分を目視レビューして適用
生成された変更をschema.prismaに反映する -
prisma migrate devを実行
マイグレーション名を指定してSQLファイルを生成・適用する -
prisma generateを手動実行(v7必須)
v7からはmigrate dev後もprisma generateの自動実行が廃止された。スキーマ変更後は必ず手動で実行すること
# スキーマ変更後の標準手順(Prisma v7)
npx prisma migrate dev --name add_phone_to_user
npx prisma generate
migrate dev vs db push の使い分けとClaude Codeへの指示方法
Prismaには目的の異なる3つのマイグレーションコマンドがある。Claude Codeへの指示時にも、どのコマンドを使うべきかを明示することが重要だ。
| コマンド | 用途 | マイグレーションファイル | shadow DB | 本番利用 |
|---|---|---|---|---|
prisma migrate dev | 開発環境のスキーマ変更 + 履歴記録 | 生成する | 必要 | ✗ |
prisma db push | プロトタイピング・スキーマ実験 | 生成しない | 不要 | ✗ |
prisma migrate deploy | 本番・ステージングへの適用 | 適用のみ(生成しない) | 不要 | ✓ |
使い分けの判断フロー:
- スキーマを「試してみたい」段階 →
db push - 変更が確定して履歴として残したい →
migrate dev - CI/CDで本番に適用 →
migrate deploy(人間がレビュー済みのファイルのみ)
db push でスキーマ実験を重ねた後、内容が確定したら migrate dev でマイグレーションファイルを正式に生成するワークフローが推奨される。なお、db push による変更は migrate dev の履歴には保存されないため注意が必要だ。
Claude Codeへの指示時は「db pushで試して、確定したらmigrate devで履歴化して」のように段階を明示すると、不必要なマイグレーションファイルの生成を防げる。
生成結果の検証チェックリスト
Claude Codeが生成したスキーマを適用する前に、以下を必ず人間が確認する:
- IDフィールドの型と生成方法が既存モデルと統一されているか
- リレーションの方向(1対多・多対多)が要件通りか
-
onDelete/onUpdateの挙動が意図通りか - インデックスの設定は適切か(特に外部キー)
- Enum値の命名がプロジェクト規約に従っているか
-
@@mapによるテーブル名がスネークケースで正しく設定されているか - v7環境では
prisma generateの手動実行が必要なことを把握しているか
Claude Codeとの効果的な対話パターン
反復改善:「ここを直して」の伝え方
Claude Codeとのスキーマ設計は一発で完成させようとせず、反復的に改善するアプローチが効果的だ。
効果的な修正指示の例:
生成されたスキーマに以下の修正をお願いします。
1. OrderItem の unitPrice は Decimal 型にしてほしい(小数点以下2桁対応)
2. Order に @index([userId, status]) を追加してほしい
3. Product の stock は 0 以上の制約をアプリ層で担保するので、スキーマには書かない
既存のフィールドは変更しないこと。
修正箇所と理由をセットで伝えることで、Claude Codeは意図した変更のみを加え、他のフィールドを意図せず変更するリスクを抑えられる。
コンテキストの維持:schema.prismaをそのまま貼るべきか
schema.prismaが大きくなった場合、全文を毎回貼り付けるのは非効率だ。以下の戦略が有効:
- 差分を伝える: 「現在の User モデルは〇〇のようになっています(抜粋)。ここに〇〇を追加してください」
- 関連モデルのみ貼る: 変更対象と直接リレーションを持つモデルだけを貼る
- CLAUDE.mdで共通方針を管理: 命名規則・型の選択は毎回書かずCLAUDE.mdに委ねる
Claude Codeはプロジェクト内のファイルを直接参照できるため、「prisma/schema.prisma のUserモデルに〇〇を追加して」という指示だけで十分なことが多い。
複数ファイルリファクタリングとの連携
スキーマ変更は schema.prisma だけでなく、Prisma Clientを使うサービス層・リポジトリ層のファイルにも波及する。Claude Codeにマルチファイルのリファクタリングを依頼する際は、影響範囲を明示して指示する。変更の影響が複数ファイルに及ぶ場合のアプローチは、claude-codeシリーズの他記事でも解説している。
よくあるミスと対処法
スキーマが意図と違う構造になるケース
ケース1:IDの型が Int になる
原因:既存モデルとの整合情報をプロンプトに含めていない
対処:「IDはすべて String @id @default(cuid())」とCLAUDE.mdに明記
ケース2:リレーションが単方向になる
原因:「1対多」という指示だけでは双方向リレーションの意図が伝わりにくい
対処:「User から複数の Order を取得できるようにする(双方向リレーション)」と明示
ケース3:テーブル名がPascalCaseになる
原因:@@map を使う規約をClaude Codeが知らない
対処:CLAUDE.mdに「テーブル名はスネークケース、@@map で指定」と記述
マイグレーション生成の落とし穴5選
| やりがちな間違い | 正しい操作 | 理由 |
|---|---|---|
db push だけで本番に適用 | migrate dev でマイグレーションファイルを生成し migrate deploy で適用 | db push は履歴を残さないため、スキーマドリフト追跡が不可能になる |
migrate dev を本番DBに直接実行 | CI/CDで migrate deploy を使用 | migrate dev は開発環境専用。shadow database を使用し、本番DBで実行すると予期せぬDB操作が発生する可能性がある |
v7でスキーマ変更後に prisma generate を忘れる | スキーマ変更 → migrate dev → prisma generate を必ずセットで実行 | v7からは migrate dev / db push 後の prisma generate 自動実行が廃止された |
| shadow database の設定漏れ(Supabase等) | shadowDatabaseUrl を明示的に設定(v7 は prisma.config.ts、v6.19以前は schema.prisma の datasource ブロック) | クラウドホスト型DBは自動的なDB作成・削除が制限される場合があり、migrate dev が失敗する |
Claude Codeに migrate deploy を実行させる | migrate deploy は人間が差分を確認してから手動実行 | 本番DBへのマイグレーション適用はAIの判断に委ねるべきでない(後述) |
Claude Codeに任せてはいけない操作
Claude Codeはスキーマ生成・マイグレーション草案の作成に非常に優れているが、実行を委ねてはいけない操作が存在する。
絶対にAIに委ねてはいけない操作:
1. 本番DBへの migrate deploy 実行判断
本番データベースへのマイグレーション適用は、取り返しのつかないデータ損失を引き起こす可能性がある操作だ。Claude Codeがスキーマ変更の意図を誤解していた場合、カラムの削除・型の変更・外部キー制約の追加が本番データを破壊しうる。
原則:migrate deploy は人間がSQLを目視確認し、ステージング環境での検証を経てから実行する。
# マイグレーションファイルの内容を必ず確認する
cat prisma/migrations/YYYYMMDD_HHMMSS_migration_name/migration.sql
# ステージングで検証後、本番で実行
DATABASE_URL=<本番DB> npx prisma migrate deploy
2. shadow databaseの削除・変更
Claude Codeが「shadow databaseが不要」と判断して shadowDatabaseUrl の設定を削除すると、migrate dev が失敗するケースが発生する。
3. 既存マイグレーションファイルの編集
prisma/migrations/ 配下のファイルをClaude Codeに直接編集させてはいけない。一度生成されたマイグレーションファイルを変更すると、スキーマドリフト検出が誤動作する。
マイグレーション後の自動フォーマット・検証フックの設定についてはClaude Code hooks実践ガイドを参照してほしい。
よくある質問
Q1. Claude CodeはPrisma Clientのクエリも書いてくれますか?
書いてくれる。findMany の条件絞り込み・include による関連モデルの結合取得・upsert や createMany の一括操作まで、型安全なクエリを生成できる。「prisma.user.findMany で、メールアドレスに特定のドメインを含む、かつ直近30日以内に作成された、注文数上位10件のユーザーを取得して」のように自然言語で指示できる。ただし、生成されたクエリはPrisma Clientの型チェックで検証し、想定外の include による N+1 問題が発生していないかを確認すること。
Q2. shadow databaseが不要な環境での注意点は?
db push と migrate deploy では shadow database は使われない。MongoDB は Prisma Migrate 自体が非対応で db push を使うため、shadow database の概念がそもそも登場しない。一方 SQLite は migrate dev をサポートしており、shadow database は一時ファイルとして自動作成・削除されるため、shadowDatabaseUrl の明示設定が不要というだけだ。PostgreSQLでローカル開発する場合も同様に、Prismaが自動的にshadow databaseを作成・削除する。Supabase等のクラウドホスト型DBで migrate dev を使う場合のみ、shadowDatabaseUrl の明示的な設定が必要になる。設定場所はバージョンで異なり、v7 では prisma.config.ts、v6.19以前では schema.prisma の datasource ブロックに書く(Prisma Config ファイル自体は v6.13 で GA になっている)。
// prisma.config.ts(Prisma v7 / Supabase等のクラウドDB使用時)
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
shadowDatabaseUrl: env("SHADOW_DATABASE_URL"),
},
});
// schema.prisma(Prisma v6.19以前)に shadowDatabaseUrl を直接設定する場合
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}
Q3. schema.prismaが大きくなったときの分割管理は?
Prisma v6以降では、prismaSchemaFolder 機能(プレビュー)を使うことで複数ファイルにスキーマを分割できる。generator client と datasource db を含むメインファイルと、ドメイン別のモデルファイルに分ける構成が一般的だ。Claude Codeに「user関連のモデルのみ」「order関連のモデルのみ」と伝えれば、分割されたファイル単位で作業できる。
Q4. Prisma以外のORMでも同じアプローチは使えますか?
基本的なアプローチ(CLAUDE.mdへの設計方針記述・具体的なbefore/after指示・マイグレーション実行はAIに委ねない)はDrizzle ORM・TypeORM・MikroORMなどにも応用できる。ただし各ORMのスキーマ記法・コマンド体系が異なるため、CLAUDE.mdにはORM固有の構文例も含めて記述することを推奨する。
Q5. CLAUDE.mdに書く内容の更新タイミングはいつですか?
以下のタイミングで更新を検討する:
- DBの変更時:新しいDB(SQLite → PostgreSQL移行など)を採用したとき
- 命名規則の変更時:プロジェクト全体で命名規則を統一・変更したとき
- Prismaバージョンアップ時:v6→v7のように破壊的変更がある場合は必ず更新
- 設計方針の変更時:IDの型をcuid()からuuid()に変更するなど、プロジェクト全体の方針が変わったとき
CLAUDE.mdは「Claude Codeへの恒久的なブリーフィング書」と捉え、プロジェクトの設計判断が変わるたびに更新することで、AIとの対話品質を継続的に維持できる。
Q6. Prismaのバージョン確認方法は?
現在使用しているPrismaのバージョンは以下のコマンドで確認できる:
npx prisma --version
本記事はPrisma v6系(最新v6.19.2)およびv7系(最新v7.6.0)を対象としている。v7からは migrate dev および db push 後の prisma generate 自動実行が廃止されたため、バージョンによって挙動が異なる重要な変更点だ。v5以前から移行する場合はPrisma公式のv7移行ガイドを必ず確認すること。
Q7. prisma migrate dev 実行時に shadow database エラーが出た場合の対処は?
Error: P3014: Prisma Migrate could not create the shadow database.
このエラーはSupabase等のクラウドホスト型DBを使用しているときに migrate dev を実行すると発生する。対処法は2つだ:
- ローカルDB(Docker等)を shadow database として用意し、
shadowDatabaseUrlに設定する - スキーマ実験フェーズは
db pushに切り替え、確定後にmigrate devを使うワークフローに変更する
まとめ
Prisma × Claude Codeの組み合わせは、スキーマ設計の効率を大幅に向上させる。ただし「AIに任せればOK」ではなく、設計意図の事前共有と実行コマンドの人間判断が品質を左右する。
実践のファーストステップとして、CLAUDE.mdにプロジェクトのPrisma設計方針を追記してみてほしい。最初の1スキーマ変更から、生成品質の違いを実感できるはずだ。
CLAUDE.mdのより詳細な設計パターンはCLAUDE.md設計ガイドで、Claude Codeのhooks設定(マイグレーション後の自動フォーマット含む)はClaude Code hooks実践ガイドで解説している。
