はじめに
Prismaを使っていて「複雑な集計クエリはORMのビルダーでは書けないから、しかたなく$queryRawで生SQLを書いた」という経験はないだろうか。問題は戻り値がunknown[]になることだ。手動でキャストしてもPrismaのスキーマと同期が取れず、スキーマが変わったときに型エラーが出ない。
Prisma v6で登場したTypedSQLはその問題を解決する。.sqlファイルに生SQLを書くだけで、TypeScriptの型付きメソッドが自動生成される。Claude Codeに生SQLを書かせて、型生成コマンドを実行して、型安全な呼び出しコードを追加する——このループがスムーズに回るのがTypedSQLとClaude Codeの相性の良さだ。
本記事はPrismaのAIガードレールやマイグレーション規約を扱った既存記事(claude-code-prisma-orm)の続編として、v6の新機能に特化して解説する。
TypedSQL——型安全なraw SQLをClaude Codeと組み合わせる
従来の$queryRawの限界
$queryRawの戻り値はunknown[]だ。実際に何が返ってくるかはSQLを読まないと分からず、型アサーションを手書きするしかない。スキーマが変わっても型エラーが出ないため、バグが静かに紛れ込む余地がある。
TypedSQLはこの問題を構造から解決する:
-- prisma/sql/getActiveUsers.sql
SELECT id, email, created_at
FROM "User"
WHERE is_active = true
AND created_at > $1
ORDER BY created_at DESC
LIMIT $2;# DBに接続した状態で型を生成
npx prisma generate --sqlimport { getActiveUsers } from '@prisma/client/sql';
// 戻り値の型が自動で推論される
const users = await prisma.$queryRawTyped(
getActiveUsers(new Date('2025-01-01'), 100)
);
// users: Array<{ id: string; email: string; created_at: Date }>$queryRawとTypedSQLを比較すると:
| 項目 | $queryRaw | TypedSQL |
|---|---|---|
| 戻り値の型 | unknown[](手動キャスト) | 自動推論 |
| パラメータの型 | 型なし | 型付き |
| SQLファイル分離 | なし(文字列埋め込み) | あり(.sqlファイル) |
Claude Codeとの組み合わせ方
TypedSQLの.sqlファイルは独立したファイルとして追加される。Claude Codeが既存コードを変更せずに、新しいSQLファイルだけを追加できる点が重要だ。
典型的な指示パターン:
prisma/sql/getMonthlyRevenue.sql を作成してください。
月ごとの売上合計を計算するSQLを書いてください。
パラメータはstart_date(Date)とend_date(Date)。
PostgreSQLの $1 $2 プレースホルダーを使うこと。
作成後に npx prisma generate --sql を実行して型を確認してください。prisma generate --sqlを依頼の中に含めておくことで、Claude Codeが型生成まで行い、型エラーがあれば即座に検出できる。CLAUDE.mdに「TypedSQLを使うときはgenerate --sqlを実行する」と書いておくと、このフローが自動的に維持される。
なお、TypedSQLは動的なカラム選択(実行時にカラムが変わる)には対応していない。その場合は従来の$queryRawを使う。
Prisma Postgres——ゼロ設定で始めるマネージドDB
Prisma Postgresは、Prismaが提供するマネージドPostgreSQLサービスだ。Cloudflare Workers + unikernel + ベアメタルのインフラ上に構築されており、コネクションプールとグローバルキャッシュ(Prisma Accelerate)が最初から内蔵されている。
サーバーレス・エッジ環境での「DBコネクションが枯渇する」問題を、追加設定なしで解消できる点が特徴だ。
無料枠の詳細(料金プランは変更の可能性があるためprisma.io/pricingで最新情報を確認してほしい):
- 月100,000オペレーション
- ストレージ1GiB
- 最大10データベース/ワークスペース
接続文字列はprisma+postgres://スキームを使う形になり、既存のPrismaコードを変更せずにそのまま接続できる。
Prisma Accelerate——サーバーレス時代のコネクションプール+キャッシュ
Prisma Postgresには組み込まれているが、自前のPostgreSQL(Neon・Supabase等)にもAccelerate層を追加できる。コネクションプール(PgBouncerがリクエストごとの新規接続を制御)とグローバルエッジキャッシュの2つが主な機能だ。
cacheStrategyでクエリ単位のキャッシュ設定ができる:
// TTL + SWR: 5分間新鮮、+2分はstaleを返しながらバックグラウンドで更新
const categories = await prisma.category.findMany({
cacheStrategy: {
ttl: 60 * 5, // 5分間はキャッシュ
swr: 60 * 2, // その後2分はstaleを返しつつバックグラウンドで再取得
},
});
// キャッシュヒット確認
const { data, info } = await prisma.user
.count({ cacheStrategy: { ttl: 60, swr: 600 } })
.withAccelerateInfo();
console.log(info?.cacheStatus); // "hit" | "miss" | "swr" | "none"Claude Codeへの指示では「Prisma AccelerateのcacheStrategyをこのクエリに追加して、頻繁に変わらないマスターデータなのでswr付きで」という形が通りやすい。swr(Stale-While-Revalidate)のコンセプトを知っていれば、意図した設定が生成される。
Prisma MCPサーバー(補足)
MCPの詳細な設定と規約については既存記事(claude-code-prisma-orm)を参照してほしい。v6ではmigrate-status・migrate-dev・prisma-studioなどのツールが使えるローカルMCPと、Prisma Postgresをリモートから管理するリモートMCPの2種類が提供されている。
リモートMCPの利用規約としてCLAUDE.mdに書いておくべき点が一つある。本番DBへのSQL実行は読み取り専用操作に限定し、データ変更を伴う操作は人間が確認した上で実行する、というルールだ。
まとめ
Prisma v6でClaude Codeとの組み合わせが特に変わるのは、TypedSQLによるraw SQLの扱い方だ。「生SQLが必要な場面」でClaude Codeに.sqlファイルを書かせ、generate --sqlで型を生成し、型付きの呼び出しコードを追加する——このフローが確立されると、複雑な集計クエリをunknown[]の戻り値で受け取るパターンから抜け出せる。
CLAUDE.mdに「TypedSQLを使う場合はprisma/sql/にファイルを作りgenerate --sqlを実行する」と書いておくことが、このフローを自動的に維持する最初のステップだ。

コメント