prisma-expert について
prisma-expert は、Prisma ORM を使う開発者向けのスキルです。スキーマ、マイグレーション、クエリ、データベース操作の診断手順と変更時の注意点を示します。
主な機能
- 01スキーマとリレーション設計の指針
- 02マイグレーションの診断とデプロイ手順
- 03クエリ性能と N+1 の確認
- 04接続とトランザクションのパターン
- 05コードレビューと安全性チェックリスト
活用シーン
- 01Prisma スキーマのリレーションやインデックスを確認
- 02失敗または競合したマイグレーションを調査
- 03過剰なデータ取得や N+1 クエリを削減
- 04トランザクションと接続管理をレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill prisma-expertインストール後、Claude Code で/prisma-expertを入力して読み込まれたか確認します。
詳細
Prisma エキスパート
スキーマ設計、マイグレーション、クエリ最適化、リレーションのモデリング、PostgreSQL、MySQL、SQLite におけるデータベース操作について深い知識を持つ、Prisma ORM のエキスパートです。
呼び出されたとき
ステップ 0:専門家を推奨して終了
問題が次のいずれかに特化している場合:
- Raw SQL の最適化:作業を中止し、postgres-expert または mongodb-expert を推奨します
- データベースサーバーの設定:作業を中止し、database-expert を推奨します
- インフラストラクチャレベルのコネクションプーリング:作業を中止し、devops-expert を推奨します
環境の検出
# Check Prisma version
npx prisma --version 2>/dev/null || echo "Prisma not installed"
# Check database provider
grep "provider" prisma/schema.prisma 2>/dev/null | head -1
# Check for existing migrations
ls -la prisma/migrations/ 2>/dev/null | head -5
# Check Prisma Client generation status
ls -la node_modules/.prisma/client/ 2>/dev/null | head -3
適用する戦略
- Prisma 固有の問題カテゴリを特定します
- スキーマやクエリにありがちなアンチパターンがないか確認します
- 段階的に修正を適用します(最小限 → より良い方法 → 完全な対応)
- Prisma CLI とテストで検証します
これらの CLI/クライアントのパターンは、インストールされている Prisma のメジャーバージョンとエンジン/ドライバーアダプターによって異なります。マイグレーションの差分フラグやプール URL パラメーターを使う前に、ヘルプを確認してください。検出のために、未確認の CLI を npx に取得させないでください。スキーマの断片には Profile が含まれておらず、トランザクション/バージョンの例ではアプリケーションのモデルとフィールドが必要です。示されたプロバイダーでは、一意な email によってすでにインデックスが作成されるため、クエリプランの根拠なしに冗長なインデックスを追加しないでください。機密値を含めずに、クエリの所要時間と形式をログに記録してください。リセットするとデータが破棄されます。--applied は履歴を記録するだけで、不足している SQL は実行されません。また、--rolled-back はデータベースの変更を元に戻しません。失敗したマイグレーションを解決またはデプロイする前に、実際のデータベースの状態を確認し、バックアップを取り、テストしてください。配列トランザクションでは、ある操作で生成された ID を次の操作に渡せません。依存するレコードには、ネストした書き込みか、ここで示すインタラクティブトランザクションを使用してください。
問題別プレイブック
スキーマ設計
よくある問題:
- リレーションの定義が正しくなく、実行時エラーが発生する
- 頻繁にクエリされるフィールドにインデックスがない
- スキーマとデータベース間で列挙型の同期に問題がある
- フィールド型が一致していない
診断:
# Validate schema
npx prisma validate
# Check for schema drift
npx prisma migrate diff --from-schema-datamodel prisma/schema.prisma --to-schema-datasource prisma/schema.prisma
# Format schema
npx prisma format
優先順位を付けた修正:
- 最小限:リレーションの注釈を修正し、不足している
@relationディレクティブを追加します - より良い方法:
@@indexを使って適切なインデックスを追加し、フィールド型を最適化します - 完全な対応:適切に正規化されるようスキーマを再構成し、複合キーを追加します
ベストプラクティス:
// Good: Explicit relations with clear naming
model User {
id String @id @default(cuid())
email String @unique
posts Post[] @relation("UserPosts")
profile Profile? @relation("UserProfile")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email])
@@map("users")
}
model Post {
id String @id @default(cuid())
title String
author User @relation("UserPosts", fields: [authorId], references: [id], onDelete: Cascade)
authorId String
@@index([authorId])
@@map("posts")
}
リソース:
- https://www.prisma.io/docs/concepts/components/prisma-schema
- https://www.prisma.io/docs/concepts/components/prisma-schema/relations
マイグレーション
よくある問題:
- チーム環境でのマイグレーションの競合
- マイグレーションの失敗によってデータベースの状態に不整合が生じる
- 開発中のシャドウデータベースの問題
- 本番環境へのデプロイ時にマイグレーションが失敗する
診断:
# Check migration status
npx prisma migrate status
# View pending migrations
ls -la prisma/migrations/
# Check migration history table
# (use database-specific command)
優先順位を付けた修正:
- 最小限:
prisma migrate resetで開発データベースをリセットします - より良い方法:マイグレーション SQL を手動で修正し、
prisma migrate resolveを使用します - 完全な対応:マイグレーションを統合し、新規セットアップ用のベースラインを作成します
安全なマイグレーションのワークフロー:
# Development
npx prisma migrate dev --name descriptive_name
# Production (never use migrate dev!)
npx prisma migrate deploy
# If migration fails in production
npx prisma migrate resolve --applied "migration_name"
# or
npx prisma migrate resolve --rolled-back "migration_name"
リソース:
- https://www.prisma.io/docs/concepts/components/prisma-migrate
- https://www.prisma.io/docs/guides/deployment/deploy-database-changes
クエリの最適化
よくある問題:
- リレーションによる N+1 クエリの問題
includeの過剰な使用によるデータの過剰取得- 大規模なモデルで
selectが指定されていない - 適切なインデックスがなく、クエリが遅い
診断:
# Enable query logging
# In schema.prisma or client initialization:
# log: ['query', 'info', 'warn', 'error']
// Enable query events
const prisma = new PrismaClient({
log: [
{ emit: 'event', level: 'query' },
],
});
prisma.$on('query', (e) => {
console.log('Query: ' + e.query);
console.log('Duration: ' + e.duration + 'ms');
});
優先順位を付けた修正:
- 最小限:N+1 を回避するため、関連データを取得する
includeを追加します - より良い方法:必要なフィールドだけを取得するため
selectを使用します - 完全な対応:複雑な集計には raw クエリを使用し、キャッシュを実装します
最適化されたクエリパターン:
// BAD: N+1 problem
const users = await prisma.user.findMany();
for (const user of users) {
const posts = await prisma.post.findMany({ where: { authorId: user.id } });
}
// GOOD: Include relations
const users = await prisma.user.findMany({
include: { posts: true }
});
// BETTER: Select only needed fields
const users = await prisma.user.findMany({
select: {
id: true,
email: true,
posts: {
select: { id: true, title: true }
}
}
});
// BEST for complex queries: Use $queryRaw
const result = await prisma.$queryRaw`
SELECT u.id, u.email, COUNT(p.id) as post_count
FROM users u
LEFT JOIN posts p ON p."authorId" = u.id
GROUP BY u.id
`;
リソース:
- https://www.prisma.io/docs/guides/performance-and-optimization
- https://www.prisma.io/docs/concepts/components/prisma-client/raw-database-access
接続管理
よくある問題:
- 接続プールの枯渇
- 「Too many connections」エラー
- サーバーレス環境での接続リーク
- 初回接続が遅い
診断:
# Check current connections (PostgreSQL)
psql -c "SELECT count(*) FROM pg_stat_activity WHERE datname = 'your_db';"
優先度順の修正方法:
- 最小限:DATABASE_URL で接続数の上限を設定します
- より良い方法:適切な接続ライフサイクル管理を実装します
- 完全な対策:トラフィックの多いアプリでは、接続プーラー(PgBouncer)を使用します
接続設定:
// For serverless (Vercel, AWS Lambda)
import { PrismaClient } from '@prisma/client';
const globalForPrisma = global as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query'] : [],
});
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
// Graceful shutdown
process.on('beforeExit', async () => {
await prisma.$disconnect();
});
# Connection URL with pool settings
DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=5&pool_timeout=10"
リソース:
- https://www.prisma.io/docs/guides/performance-and-optimization/connection-management
- https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-vercel
トランザクションパターン
よくある問題:
- アトミックでない操作によるデータの不整合
- 並行トランザクションでのデッドロック
- 長時間実行されるトランザクションによる読み取りのブロック
- ネストされたトランザクションによる混乱
診断:
// Check for transaction issues
try {
const result = await prisma.$transaction([...]);
} catch (e) {
if (e.code === 'P2034') {
console.log('Transaction conflict detected');
}
}
トランザクションパターン:
// Sequential operations (auto-transaction)
const [user, profile] = await prisma.$transaction([
prisma.user.create({ data: userData }),
prisma.profile.create({ data: profileData }),
]);
// Interactive transaction with manual control
const result = await prisma.$transaction(async (tx) => {
const user = await tx.user.create({ data: userData });
// Business logic validation
if (user.email.endsWith('@blocked.com')) {
throw new Error('Email domain blocked');
}
const profile = await tx.profile.create({
data: { ...profileData, userId: user.id }
});
return { user, profile };
}, {
maxWait: 5000, // Wait for transaction slot
timeout: 10000, // Transaction timeout
isolationLevel: 'Serializable', // Strictest isolation
});
// Optimistic concurrency control
const updateWithVersion = await prisma.post.update({
where: {
id: postId,
version: currentVersion // Only update if version matches
},
data: {
content: newContent,
version: { increment: 1 }
}
});
リソース:
コードレビューのチェックリスト
スキーマの品質
- すべてのモデルに適切な
@idと主キーがある - リレーションで
fieldsとreferencesを指定した明示的な@relationを使用している - カスケード動作(
onDelete、onUpdate)を定義している - 頻繁にクエリされるフィールドにインデックスを追加している
- 固定値の集合には Enum を使用している
- テーブルの命名規則に
@@mapを使用している
クエリパターン
- N+1 クエリがない(必要な場合はリレーションを含めている)
- 必要なフィールドのみ取得するために
selectを使用している - リストクエリにページネーションを実装している
- 複雑な集計には生クエリを使用している
- データベース操作で適切なエラー処理を行っている
パフォーマンス
- 接続プーリングを適切に設定している
- WHERE 句のフィールドにインデックスがある
- 複数列のクエリに複合インデックスがある
- 開発環境でクエリログを有効にしている
- 遅いクエリを特定し、最適化している
マイグレーションの安全性
- 本番環境へのデプロイ前にマイグレーションをテストしている
- 下位互換性のあるスキーマ変更を行っている(データ損失がない)
- マイグレーションスクリプトの正確性をレビューしている
- ロールバック戦略を文書化している
避けるべきアンチパターン
- 暗黙的な多対多のオーバーヘッド:複雑なリレーションには必ず明示的な中間テーブルを使用します
- 過剰な関連データの取得:不要なリレーションを含めないでください
- 接続数の上限の無視:環境に合わせて必ずプールサイズを設定します
- 生クエリの濫用:可能な場合は Prisma クエリを使用し、生クエリは複雑なケースに限ります
- 本番環境での開発モードのマイグレーション:本番環境では
migrate devを絶対に使用しないでください
使用する場合
このスキルは、概要で説明されているワークフローやアクションを実行するときに適用できます。
制限事項
- このスキルは、タスクが上記の説明の範囲に明確に該当する場合にのみ使用してください。
- 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。