jpskill.com
🛠️ 開発・MCP コミュニティ

api-database-prisma

Prisma ORMを活用し、型安全なクエリやデータベース移行、テーブル間のリレーションなどを効率的に管理・操作することで、より安全で保守性の高いデータベース開発を実現するSkill。

📜 元の英語説明(参考)

Prisma ORM, type-safe queries, migrations, relations

🇯🇵 日本人クリエイター向け解説

一言でいうと

Prisma ORMを活用し、型安全なクエリやデータベース移行、テーブル間のリレーションなどを効率的に管理・操作することで、より安全で保守性の高いデータベース開発を実現するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o api-database-prisma.zip https://jpskill.com/download/10236.zip && unzip -o api-database-prisma.zip && rm api-database-prisma.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10236.zip -OutFile "$d\api-database-prisma.zip"; Expand-Archive "$d\api-database-prisma.zip" -DestinationPath $d -Force; ri "$d\api-database-prisma.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して api-database-prisma.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → api-database-prisma フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Prisma ORM を使用したデータベース

クイックガイド: 自動生成された TypeScript 型による型安全なデータベースクエリには、Prisma ORM を使用します。宣言的なマイグレーションによるスキーマファースト設計。リレーションには include を、アトミックな操作には $transaction を使用します。接続枯渇を避けるため、開発環境ではシングルトンパターンが必要です。インタラクティブトランザクションのコールバック内では、常に tx ( prisma ではない) を使用してください。


<critical_requirements>

重要: この Skill を使用する前に

すべてのコードは CLAUDE.md のプロジェクト規約に従う必要があります (kebab-case、名前付きエクスポート、インポート順序、import type、名前付き定数)

(ホットリロードによる接続枯渇を防ぐため、開発環境では PrismaClient にシングルトンパターンを必ず使用する必要があります)

(アトミック性を保証するため、インタラクティブトランザクションのコールバック内では、tx パラメータ ( prisma ではない) を必ず使用する必要があります)

(リレーショナルクエリには、include またはネストされた select を必ず使用してください - 同じクエリでリレーションを取得することで N+1 問題を回避します)

(すべての外部キーリレーションシップに対して、明示的な fieldsreferences を持つ @relation を必ず定義してください)

</critical_requirements>


自動検出: prisma, @prisma/client, PrismaClient, prisma.schema, prisma migrate, findUnique, findMany, include, $transaction

使用すべき場合:

  • 自動生成された TypeScript 型による型安全なデータベースクエリ
  • 宣言的なマイグレーションによるスキーマファースト開発
  • 強力なリレーショナルデータモデリングを必要とするアプリケーション
  • Prisma Studio GUI を使用した迅速なプロトタイピング

使用すべきでない場合:

  • 複雑なクエリに対して生の SQL パフォーマンスが必要な場合 (Prisma はオーバーヘッドを追加します)
  • コールドスタートを最小限に抑える必要がある Edge/サーバーレス環境 (より軽量な ORM を検討してください)
  • TypeScript 以外のプロジェクト (主な利点を失います)
  • 生成される SQL を細かく制御する必要がある場合

カバーされる主要なパターン:

  • PrismaClient シングルトン (開発環境でのホットリロードの安全性)
  • 型安全なフィルタとページネーションによる CRUD 操作
  • include とネストされた select を使用したリレーショナルクエリ
  • トランザクション (ネストされた書き込み、バッチ、インタラクティブ)
  • スキーマ設計 (モデル、リレーション、enum、インデックス)

詳細なリソース:

  • examples/core.md - シングルトン設定、CRUD、フィルタリング、ページネーション
  • examples/relations.md - リレーショナルクエリ、include、N+1 問題の防止
  • examples/transactions.md - アトミック操作、インタラクティブトランザクション、エラー処理
  • reference.md - 意思決定フレームワーク、アンチパターン、パフォーマンス

<philosophy>

Philosophy

Prisma ORM は、型安全なデータベースクライアントを生成する宣言的なスキーマ言語を提供します。スキーマは、データモデル、TypeScript 型、およびマイグレーションの唯一の信頼できる情報源として機能します。

コア原則:

  1. スキーマファースト設計 - schema.prisma でモデルを定義し、その他すべてを生成します
  2. あらゆる場所での型安全性 - すべてのクエリはスキーマに基づいて完全に型付けされます
  3. 宣言的なマイグレーション - スキーマの変更は自動的にマイグレーション SQL を生成します
  4. 直感的な API - クエリは英語のように読めます ( prisma.user.findMany() )

</philosophy>


<patterns>

コアパターン

パターン 1: PrismaClient シングルトン

開発環境でのホットリロード中に接続プールが枯渇するのを防ぐために、シングルトンパターンを使用します。これがないと、ホットリロードごとに独自の接続プールを持つ新しい PrismaClient が作成され、データベース接続がすぐに枯渇します。

// lib/db/client.ts
import { PrismaClient } from "@prisma/client";

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined;
};

const createPrismaClient = () => {
  return new PrismaClient({
    log:
      process.env.NODE_ENV === "development"
        ? ["query", "error", "warn"]
        : ["error"],
  });
};

export const prisma = globalForPrisma.prisma ?? createPrismaClient();

if (process.env.NODE_ENV !== "production") {
  globalForPrisma.prisma = prisma;
}

利点: globalThis はホットリロード間で永続化され、条件付きロギングは本番環境でのノイズを回避します

サーバーレス接続パターンについては、examples/core.md を参照してください。


パターン 2: スキーマ設計

リレーション、制約、およびデフォルトを使用してモデルを定義します。スキーマは信頼できる情報源です。

model User {
  id        String   @id @default(cuid())
  email     String   @unique
  name      String?
  role      Role     @default(USER)
  posts     Post[]
  profile   Profile?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("users")
}

model Post {
  id        String   @id @default(cuid())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id], onDelete: Cascade)
  authorId  String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@index([authorId])
  @@map("posts")
}

利点: 衝突耐性のある ID には cuid() 、変更を自動追跡するには @updatedAt 、孤立を防ぐには onDelete: Cascade を持つ @relation 、外部キーには @@index 、コード内の PascalCase で snake_case DB テーブルには @@map


パターン 3: 型安全なフィルタを使用した CRUD

すべてのクエリは、スキーマに基づいて完全に型付けされています。主な操作:

const DEFAULT_PAGE_SIZE = 20;
const MAX_PAGE_SIZE = 100;

// 一意のフィールドで検索 - T | null を返します
const user = await prisma.user.findUnique({
  where: { email: "alice@example.com" },
});

// フィルタ + ページネーションで多数を検索
const users = await prisma.user.findMany({
  where: {
    role: { in: ["USER", "MODERATOR"] },
    createdAt: { gte: new Date("2024-01-01") },
  },
  orderBy: { name: "asc" },
  take: DEFAULT_PAGE_SIZE,
});

// Upsert - アトミックな作成または更新
const upserted = await prisma.user.upsert({
  where: { email: "alice@example.com" },
  create: { email: "alice@example.com", name: "Alice" },
  update: { name: "Alice Updated" },
});

利点: 型安全な操作はコンパイル時にエラーをキャッチし、findUniqueT | null を返し、null 処理を強制し、upsert はアトミックです

詳しくは examples/core.md を参照してください

(原文はここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Database with Prisma ORM

Quick Guide: Use Prisma ORM for type-safe database queries with auto-generated TypeScript types. Schema-first design with declarative migrations. Use include for relations, $transaction for atomic operations. Singleton pattern required in development to avoid connection exhaustion. Always use tx (not prisma) inside interactive transaction callbacks.


<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use the singleton pattern for PrismaClient in development to prevent connection exhaustion from hot reloading)

(You MUST use tx parameter (NOT prisma) inside interactive transaction callbacks to ensure atomicity)

(You MUST use include or nested select for relational queries - avoid N+1 by fetching relations in the same query)

(You MUST define @relation with explicit fields and references for all foreign key relationships)

</critical_requirements>


Auto-detection: prisma, @prisma/client, PrismaClient, prisma.schema, prisma migrate, findUnique, findMany, include, $transaction

When to use:

  • Type-safe database queries with auto-generated TypeScript types
  • Schema-first development with declarative migrations
  • Applications requiring strong relational data modeling
  • Rapid prototyping with Prisma Studio GUI

When NOT to use:

  • Need raw SQL performance for complex queries (Prisma adds overhead)
  • Edge/serverless requiring minimal cold start (consider lighter ORMs)
  • Non-TypeScript projects (lose primary benefit)
  • Need fine-grained control over generated SQL

Key patterns covered:

  • PrismaClient singleton (development hot reload safety)
  • CRUD operations with type-safe filters and pagination
  • Relational queries with include and nested select
  • Transactions (nested writes, batch, interactive)
  • Schema design (models, relations, enums, indexes)

Detailed Resources:


<philosophy>

Philosophy

Prisma ORM provides a declarative schema language that generates type-safe database clients. The schema serves as the single source of truth for your data model, TypeScript types, and migrations.

Core principles:

  1. Schema-first design - Define models in schema.prisma, generate everything else
  2. Type safety everywhere - All queries fully typed based on your schema
  3. Declarative migrations - Schema changes automatically generate migration SQL
  4. Intuitive API - Queries read like English (prisma.user.findMany())

</philosophy>


<patterns>

Core Patterns

Pattern 1: PrismaClient Singleton

Use singleton pattern to prevent connection pool exhaustion during development hot reloading. Without this, each hot reload creates a new PrismaClient with its own connection pool, quickly exhausting database connections.

// lib/db/client.ts
import { PrismaClient } from "@prisma/client";

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined;
};

const createPrismaClient = () => {
  return new PrismaClient({
    log:
      process.env.NODE_ENV === "development"
        ? ["query", "error", "warn"]
        : ["error"],
  });
};

export const prisma = globalForPrisma.prisma ?? createPrismaClient();

if (process.env.NODE_ENV !== "production") {
  globalForPrisma.prisma = prisma;
}

Why good: globalThis persists across hot reloads, conditional logging avoids production noise

See examples/core.md for serverless connection patterns.


Pattern 2: Schema Design

Define models with relations, constraints, and defaults. The schema is the source of truth.

model User {
  id        String   @id @default(cuid())
  email     String   @unique
  name      String?
  role      Role     @default(USER)
  posts     Post[]
  profile   Profile?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("users")
}

model Post {
  id        String   @id @default(cuid())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id], onDelete: Cascade)
  authorId  String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@index([authorId])
  @@map("posts")
}

Why good: cuid() for collision-resistant IDs, @updatedAt auto-tracks changes, @relation with onDelete: Cascade prevents orphans, @@index on foreign keys, @@map for snake_case DB tables with PascalCase in code


Pattern 3: CRUD with Type-Safe Filters

All queries are fully typed based on your schema. Key operations:

const DEFAULT_PAGE_SIZE = 20;
const MAX_PAGE_SIZE = 100;

// Find by unique field - returns T | null
const user = await prisma.user.findUnique({
  where: { email: "alice@example.com" },
});

// Find many with filters + pagination
const users = await prisma.user.findMany({
  where: {
    role: { in: ["USER", "MODERATOR"] },
    createdAt: { gte: new Date("2024-01-01") },
  },
  orderBy: { name: "asc" },
  take: DEFAULT_PAGE_SIZE,
});

// Upsert - atomic create-or-update
const upserted = await prisma.user.upsert({
  where: { email: "alice@example.com" },
  create: { email: "alice@example.com", name: "Alice" },
  update: { name: "Alice Updated" },
});

Why good: Type-safe operations catch errors at compile time, findUnique returns T | null forcing null handling, upsert is atomic

See examples/core.md for complete CRUD operations, filtering, and pagination patterns.


Pattern 4: Relational Queries

Fetch related data efficiently using include or nested select to avoid N+1 queries.

// Include related records - single query
const userWithPosts = await prisma.user.findUnique({
  where: { id: userId },
  include: {
    posts: {
      where: { published: true },
      orderBy: { createdAt: "desc" },
      take: 10,
    },
    profile: true,
  },
});

// Select specific fields only - smaller payload
const userSummary = await prisma.user.findUnique({
  where: { id: userId },
  select: {
    id: true,
    name: true,
    posts: { select: { id: true, title: true } },
  },
});

Why good: Single query avoids N+1, include fetches all fields, select reduces payload. Never loop queries per record — use include or select instead.

See examples/relations.md for relation filters, many-to-many, self-relations, include vs select, and N+1 anti-patterns.


Pattern 5: Transactions

Ensure atomic operations across multiple writes. Three types available:

// Nested writes - implicit transaction (cleanest for related records)
const user = await prisma.user.create({
  data: {
    email: "alice@example.com",
    name: "Alice",
    profile: { create: { bio: "Developer" } },
    posts: { create: [{ title: "First Post", published: true }] },
  },
  include: { profile: true, posts: true },
});

// Interactive transaction - ALWAYS use tx, never prisma
return await prisma.$transaction(async (tx) => {
  const sender = await tx.account.update({
    where: { id: fromId },
    data: { balance: { decrement: amount } },
  });
  if (sender.balance < MINIMUM_BALANCE) throw new Error("Insufficient funds");
  return await tx.account.update({
    where: { id: toId },
    data: { balance: { increment: amount } },
  });
});

Why good: Nested writes for related records, interactive transactions enable business logic with automatic rollback. Using prisma instead of tx inside the callback bypasses transaction context.

See examples/transactions.md for batch transactions, error handling, optimistic concurrency, and transaction options.


Pattern 6: Connection Management

Handle $disconnect() on beforeExit to prevent connection leaks. For serverless environments, use a connection pooler (PgBouncer, Prisma Accelerate) via a separate DATABASE_URL_WITH_POOLER environment variable.

See examples/core.md for graceful shutdown and serverless connection patterns.

</patterns>


<red_flags>

RED FLAGS

High Priority Issues:

  • Creating PrismaClient on every import - exhausts database connections during hot reload
  • Using prisma instead of tx in interactive transactions - bypasses transaction context
  • N+1 queries in loops - use include or select instead
  • Missing @relation attributes - ambiguous foreign keys cause migration errors

Medium Priority Issues:

  • No indexes on frequently filtered columns - slow queries as data grows
  • Offset pagination on large tables - performance degrades linearly
  • Missing onDelete cascade - orphaned records when parent deleted
  • Fetching all fields with include when only some needed - use select

Gotchas & Edge Cases:

  • createMany doesn't return created records (use createManyAndReturn on PostgreSQL/CockroachDB/SQLite)
  • updateMany and deleteMany don't automatically update @updatedAt fields
  • Implicit many-to-many tables can't have extra fields - use explicit join model
  • Json fields are typed as JsonValue - need runtime validation at parse boundary
  • Decimal fields return Prisma.Decimal type - convert with .toNumber()
  • Interactive transactions have default 5s timeout - increase with timeout option
  • Interactive transactions hold database connections - keep them short
  • findFirst without orderBy returns non-deterministic results
  • Enum changes require a migration to add/remove values

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md

(You MUST use the singleton pattern for PrismaClient in development to prevent connection exhaustion from hot reloading)

(You MUST use tx parameter (NOT prisma) inside interactive transaction callbacks to ensure atomicity)

(You MUST use include or nested select for relational queries - avoid N+1 by fetching relations in the same query)

(You MUST define @relation with explicit fields and references for all foreign key relationships)

Failure to follow these rules will exhaust database connections, break transaction atomicity, cause N+1 performance problems, and create unclear relation definitions.

</critical_reminders>