schema.prisma
Prisma の中核。1 ファイルでデータソース・Client 設定・テーブル(model)を宣言する DSL。
ファイルの基本構造
// 1. データソース
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// 2. Generator(Client 生成)
generator client {
provider = "prisma-client-js"
}
// 3. Enum
enum Role {
USER
ADMIN
}
// 4. Model(テーブル)
model User {
id String @id @default(cuid())
email String @unique
role Role @default(USER)
}
datasource ブロック
- provider:
postgresql/mysql/sqlite/sqlserver/mongodb/cockroachdb - url: 接続文字列
- directUrl: PgBouncer 経由時のマイグレーション用直接接続
- schemas: 複数スキーマ対応(preview)
- relationMode:
"foreignKeys"(既定)/"prisma"(FK なし、PlanetScale 等)
generator ブロック
generator client {
provider = "prisma-client-js"
output = "../src/generated/client" // 出力先カスタム
binaryTargets = ["native", "linux-musl-openssl-3.0.x"] // Lambda / Vercel 用
previewFeatures = ["driverAdapters", "metrics"]
}
- 複数 Generator を書けば JSON Schema / GraphQL / Zod スキーマも自動生成可
- community:
zod-prisma,prisma-trpc-generator,prisma-class-generator
model 構文
model Post {
id String @id @default(cuid())
title String
content String? // ? = NULL 許容
views Int @default(0)
published Boolean @default(false)
tags String[] // 配列(Postgres)
meta Json? // JSON / JSONB
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt // 自動更新
@@index([published, createdAt]) // 複合インデックス
@@map("posts") // テーブル名
}
主要なフィールド型
| Prisma 型 | Postgres | TS 型 |
|---|---|---|
| String | text | string |
| Int | integer | number |
| BigInt | bigint | bigint |
| Float | double precision | number |
| Decimal | decimal(p,s) | Decimal |
| Boolean | boolean | boolean |
| DateTime | timestamp(3) | Date |
| Json | jsonb | JsonValue |
| Bytes | bytea | Buffer |
| Unsupported("...") | 任意(Postgis 等) | — |
属性(@ / @@)
フィールド属性(@)
- @id — 主キー
- @unique — UNIQUE 制約
- @default(value) — デフォルト値
- @updatedAt — 自動更新タイムスタンプ
- @map("col_name") — DB の列名(snake_case 等)
- @relation — リレーション
- @db.<type> — DB 固有型(
@db.VarChar(255)等)
モデル属性(@@)
- @@id([a, b]) — 複合主キー
- @@unique([a, b]) — 複合 UNIQUE
- @@index([a, b]) — 複合インデックス
- @@map("table_name") — テーブル名
- @@schema("auth") — スキーマ指定(preview)
@default の値
| 値 | 意味 |
|---|---|
now() | 現在時刻 |
uuid() | UUID v4 |
cuid() | CUID(衝突しにくい短い ID) |
nanoid() | nanoid |
autoincrement() | SERIAL(Postgres) |
dbgenerated("...") | DB 側の式(gen_random_uuid() 等) |
| 固定値 | 0 / "draft" / false / 配列 |
ID 戦略
| 戦略 | 長所 | 短所 |
|---|---|---|
| cuid() | 短い、衝突しない、URL 安全 | 順序保証なし |
| uuid() | 標準 | 長い |
| autoincrement() | 軽量、ソート可 | 連番が露出 / 分散しにくい |
| dbgenerated("gen_random_uuid()") | DB 側で生成 | クライアント側で予測不能 |
リレーション(簡易)
詳細は リレーション ページ。最小例:
model User {
id String @id @default(cuid())
email String @unique
posts Post[]
}
model Post {
id String @id @default(cuid())
title String
authorId String
author User @relation(fields: [authorId], references: [id])
}
Enum
enum PostStatus {
DRAFT
PUBLISHED
ARCHIVED
}
model Post {
status PostStatus @default(DRAFT)
}
列の DB 固有型(@db)
model Post {
title String @db.VarChar(120)
price Decimal @db.Decimal(10, 2)
bio String? @db.Text
uuid String @db.Uuid
geom Unsupported("geometry") // PostGIS
}
JSON フィールド
model Post {
meta Json?
}
TypeScript では JsonValue 型。Zod や型キャストで構造を保証する:
type Meta = { tags: string[], views: number }
const meta = post.meta as Meta
Strict-typed JSON(Prisma の機能)
model Post {
meta Json /// @prisma/client > PostMeta
}
命名規則
- Prisma model はPascalCase 単数形:
User,BlogPost - フィールドはcamelCase:
createdAt - DB 名はスネークケースが多いので
@mapで変換
model BlogPost {
id String @id
authorId String @map("author_id")
createdAt DateTime @map("created_at")
@@map("blog_posts")
}
マルチスキーマ対応
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["public", "auth"]
}
model User {
id String @id
email String @unique
@@schema("auth")
}
model Post {
id String @id
title String
@@schema("public")
}
ビュー(preview feature)
view UserStats {
userId String @id
postCount Int
}
Prisma 自体はビューを作成しない。SQL 側で作成済みの View を読むためのもの。
schema を分割する
v5+ で複数の .prisma ファイル対応:
prisma/
├── schema/
│ ├── user.prisma
│ ├── post.prisma
│ └── _config.prisma (datasource / generator)
イントロスペクション(既存 DB 取り込み)
npx prisma db pull # DB の構造から schema.prisma を生成
既存の Postgres を Prisma 化したいときに使う。db pull で取り込み →
必要なら手で整形 → 以降は通常の migrate dev で運用。
schema 検証 / 整形
npx prisma validate
npx prisma format
VS Code 拡張
Prisma(公式)拡張機能で:
- シンタックスハイライト
- フォーマット
- 自動補完
- リレーション補完
- Lint
よくあるパターン
created / updated タイムスタンプ
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ソフトデリート
deletedAt DateTime?
実装上は middleware や $extends で「where: { deletedAt: null }」を自動注入する(→ 高度な機能)。
所有者制約(authorId 必須)
model Post {
authorId String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
@@index([authorId])
}
onDelete / onUpdate
- Cascade: 親が消えたら子も消す
- Restrict: 子があれば親を消せない
- SetNull: 親が消えたら子の FK を NULL に
- NoAction: DB のデフォルト
失敗パターン
| 症状 | 原因 |
|---|---|
| generate しても型が更新されない | node_modules キャッシュ。rm -rf node_modules/.prisma |
| field が undefined 扱い | schema 変更後 generate していない |
| 型が複雑すぎてエディタが固まる | schema を分割、include/select を絞る |
| migration が壊れた | migrate reset でローカル再生成 |
| 本番だけ違う列名 | @map を確認 |
運用ルール
schema.prisma は本番データの形を決める設計図。 PR で必ずレビュー、変更時は migration もセットでコミット、Studio での GUI 編集は厳禁。