- 开发工具
- CLI
- 代码生成
【免费下载链接】create-t3-app
The best way to start a full-stack, typesafe Next.js app
Prisma は TypeScript のための ORM であり、schema.prismaファイルでデータベーススキーマとモデルを定義し、バックエンドからデータベースとやり取りするための型安全なクライアントを生成できます。create-t3-app で Prisma を選択すると、CLI がクライアントの初期化からスキーマ生成、環境変数、npm スクリプトまでを一括でセットアップしてくれます。本記事では、生成されるsrc/server/db.tsの設計意図、スキーマファイルの構成、データベースプロバイダの切り替え方、そしてシーディングの実装手順までを、実際のリポジトリのソースコードと照らし合わせながら解説します。
Prisma とは
Prisma は TypeScript 向けのデータベースツールキット(ORM)です。schema.prismaファイルでデータベーススキーマとモデルを宣言的に定義し、そのスキーマから型安全なクライアントを生成することで、SQL を直接書かずにデータベースへアクセスできます。モデル定義に対する型が自動生成されるため、コンパイル時にフィールド名や型の誤りを検出でき、リファクタリング時の安全性も高まります。
create-t3-app では Prisma を選択すると、prismaInstaller が以下のパッケージを自動でインストールします。
- 開発依存:
prisma(CLI/スキーマ管理) - 本番依存:
@prisma/client(生成されるクライアント本体) - PlanetScale を選択した場合:
@prisma/adapter-planetscaleと@planetscale/database
バージョンは dependencyVersionMap.ts に固定マッピングされており、現時点ではprisma・@prisma/clientともに^6.6.0、アダプタは@prisma/adapter-planetscale: ^6.6.0が使用されます。npm レジストリへの問い合わせを省くことで、インストールのパフォーマンスも最適化されています。
Prisma Client:src/server/db.tsの設計
Prisma クライアントはsrc/server/db.tsに置かれ、グローバル変数としてインスタンス化されたうえでエクスポートされ、API ルートで使用されます。これは Prisma チームが Next.js 開発時のベストプラクティスとして推奨しているパターンです。
実際の生成テンプレート(db-prisma.ts)を見ると、その設計が明確にわかります。
import { env } from "~/env"; import { PrismaClient } from "../../generated/prisma"; const createPrismaClient = () => new PrismaClient({ log: env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], }); const globalForPrisma = globalThis as unknown as { prisma: ReturnType<typeof createPrismaClient> | undefined; }; export const db = globalForPrisma.prisma ?? createPrismaClient(); if (env.NODE_ENV !== "production") globalForPrisma.prisma = db;この実装が解決しているのは、Next.js のホットリロード(Fast Refresh)時に開発サーバが再起動されるたびに Prisma クライアントが多重生成され、データベース接続がリークするという問題です。globalThisにクライアントを保持し、NODE_ENVがproduction以外の場合だけグローバルに再利用する、という 2 段構えのパターンによって、開発時の再生成を防いでいます。
また、PrismaClientのlogオプションは環境によって切り替わります。
- 開発環境(
development):query(実行 SQL)、error、warnを出力 - それ以外(テスト・本番):
errorのみ
これにより、開発中はクエリログを確認しながらデバッグでき、本番ではログノイズを抑えられます。
なお、生成されるクライアントの出力先はスキーマのgenerator clientブロックでoutput = "../generated/prisma"と指定され、プロジェクト直下のgenerated/prismaに置かれる点にも注目してください(base.prisma)。
PlanetScale を選んだ場合のクライアント
データベースプロバイダとして PlanetScale を選択した場合は、db-prisma-planetscale.ts がコピーされます。こちらは Prisma のドライバアダプタ機能を使って、PlanetScale 用アダプタを直接クライアントに渡します。
import { PrismaPlanetScale } from "@prisma/adapter-planetscale"; import { env } from "~/env"; import { PrismaClient } from "../../generated/prisma"; const createPrismaClient = () => new PrismaClient({ log: env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], adapter: new PrismaPlanetScale({ url: env.DATABASE_URL }), });このアダプタを使うため、スキーマ側ではpreviewFeatures = ["driverAdapters"]を有効にしたうえで、relationMode = "prisma"(外部キー制約をデータベース側で強制しない設定)がコメント付きで追加されます(base-planetscale.prisma)。
tRPC コンテキストへの組み込み
create-t3-app では Prisma クライアントがデフォルトで tRPC のコンテキスト に含まれており、各ファイルで個別にインポートするのではなく、コンテキスト経由で利用することを推奨しています。tRPC を使う場合、createTRPCContextは次のようにdbを返します(with-auth-db.ts)。
import { db } from "~/server/db"; export const createTRPCContext = async (opts: { headers: Headers }) => { const session = await auth(); return { db, session, ...opts, }; };これにより、ルーター内ではctx.dbとして型安全にアクセスできます。実際のルーター実装(with-prisma.ts)では、次のように利用されています。
create: publicProcedure .input(z.object({ name: z.string().min(1) })) .mutation(async ({ ctx, input }) => { return ctx.db.post.create({ data: { name: input.name, }, }); }), getLatest: publicProcedure.query(async ({ ctx }) => { const post = await ctx.db.post.findFirst({ orderBy: { createdAt: "desc" }, }); return post ?? null; }),ctx.db.post.createやctx.db.post.findFirstがコンパイル時に型チェックされるため、フィールド名のタイポや存在しないフィールドへのアクセスを即座に検出できます。
スキーマファイルの構成
Prisma のスキーマファイルはプロジェクトの/prisma/schema.prismaに置かれます。ここでデータベーススキーマとモデルを定義し、Prisma クライアント生成時の元ネタになります。
Prisma を選択した場合、create-t3-app は認証ライブラリの選択(NextAuth.js/Better Auth/なし)とデータベースプロバイダに応じて、適切なスキーマテンプレートをコピーします。インストーラ(prisma.ts)のロジックは以下のとおりです。
const schemaBaseName = packages?.betterAuth.inUse ? "with-better-auth" : packages?.nextAuth.inUse ? "with-auth" : "base"; const schemaSrc = path.join( extrasDir, "prisma/schema", `${schemaBaseName}${ databaseProvider === "planetscale" ? "-planetscale" : "" }.prisma` );つまり、テンプレートディレクトリ cli/template/extras/prisma/schema 内のbase.prisma、with-auth.prisma、with-better-auth.prismaと、それぞれの-planetscale版から 1 つが選ばれ、プロジェクトのprisma/schema.prismaに書き出されます。
基本スキーマ(認証なし)
認証を使わない場合のスキーマ(base.prisma)は次のようになります。
generator client { provider = "prisma-client-js" output = "../generated/prisma" } datasource db { provider = "sqlite" url = env("DATABASE_URL") } model Post { id Int @id @default(autoincrement()) name String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([name]) }Postモデルは id/name/作成日時/更新日時の最小構成で、@@index([name])によるインデックスも定義済みです。datasourceブロックのurlはenv("DATABASE_URL")で環境変数から読み込むため、接続先をコードにハードコードしません。
NextAuth.js と組み合わせた場合
NextAuth.js と Prisma を同時に選択すると、NextAuth.js の Prisma アダプタが要求するUser・Session・Account・VerificationTokenの 4 モデルが、公式ドキュメント推奨の値でスキーマファイルに自動生成されます(with-auth.prisma)。
ポイントを整理すると、以下のとおりです。
User:idはcuid()で自動生成、emailは@uniqueAccount:providerとproviderAccountIdの複合ユニーク(@@unique([provider, providerAccountId]))、userへのリレーションはonDelete: CascadeSession:sessionTokenは@unique、userへのリレーションはonDelete: CascadeVerificationToken:identifierとtokenの複合ユニークPostモデルにもcreatedBy/createdByIdが追加され、Userとのリレーションを持ちます
また、Accountモデルのrefresh_token・access_token・id_tokenには// @db.Textというコメント付きの注釈があります。これは MySQL/SQL Server でString型(VARCHAR)のままではトークンが長すぎて保存できない問題への対策です。create-t3-app のインストーラは、データベースプロバイダがmysqlまたはplanetscaleの場合にこのコメントを自動的に有効化します(schemaText.replace("// @db.Text", "@db.Text"))。SQLite/PostgreSQL を使う場合はコメントのままで問題ありません。
デフォルトのデータベースとプロバイダの切り替え
create-t3-app のデフォルトデータベースはSQLiteです。セットアップ直後からファイルベースで動作するため、開発や PoC(概念実証)を素早く立ち上げるのには最適ですが、同時実行やスケーラビリティの面から本番環境での使用は推奨されません。
使用するデータベースを変更するには、次の 2 点を変更します。
schema.prismaのdatasourceブロックにあるproviderをpostgresqlまたはmysqlに変更- 環境変数
DATABASE_URLの接続文字列を対象データベースのものに更新
プロバイダごとの DATABASE_URL
CLI は選択したプロバイダに応じて.env/.env.exampleに接続文字列の雛形を書き込みます(envVars.ts)。
| プロバイダ | providerの値 | 生成されるDATABASE_URLの雛形 |
|---|---|---|
| SQLite(デフォルト) | sqlite | DATABASE_URL="file:./db.sqlite" |
| PostgreSQL | postgresql | DATABASE_URL="postgresql://postgres:password@localhost:5432/<appName>" |
| MySQL | mysql | DATABASE_URL="mysql://root:password@localhost:3306/<appName>" |
| PlanetScale | mysql | DATABASE_URL='mysql://YOUR_MYSQL_URL_HERE?sslaccept=strict' |
プロジェクト名(<appName>)は CLI 実行時に入力した名前がそのままデータベース名に使われます。PlanetScale の場合は、PlanetScale のコンソールで「prisma」ドロップダウンから発行された接続 URL を使い、末尾に?sslaccept=strictを付けるというガイドがコメントとして書き込まれます。
インストーラによるスキーマ変換
プロバイダを SQLite 以外にした場合、インストーラはスキーマファイルのprovider = "sqlite"を選択されたプロバイダに置換します。mysql/postgresql/planetscaleのマッピングはインストーラ内に定義されており、PlanetScale は内部的にはmysqlとして扱われます。さらに、前述のとおりmysql/planetscaleでは@db.Text注釈も同時に有効化されます。
ただし、すでにプロジェクトを作成済みの場合は、この変換は自動では行われません。providerを手で書き換えた後、pnpm db:pushなどでスキーマをデータベースに反映し、.envのDATABASE_URLを更新する必要があります。
環境変数のバリデーション
Prisma を使うプロジェクトでは、src/env.jsにDATABASE_URLのバリデーションが追加されます(with-db.js)。
DATABASE_URL: z.string().url(),@t3-oss/env-nextjsとzodによるこのバリデーションにより、DATABASE_URLが未設定・不正な形式のままnext buildやnext devを実行すると、起動時にエラーで検出されます。空文字を未定義として扱うemptyStringAsUndefined: trueの設定と合わせて、環境変数ミスによる実行時トラブルを未然に防ぎます。スキップしたい場合はSKIP_ENV_VALIDATION環境変数を指定します(Docker ビルドなどで有用です)。
package.json に追加される npm スクリプト
Prisma インストーラは、次の 5 つのスクリプトをpackage.jsonに追加します(prisma.ts)。
| スクリプト | 実行されるコマンド | 用途 |
|---|---|---|
postinstall | prisma generate | 依存関係インストール後に自動でクライアント生成 |
db:push | prisma db push | スキーマをデータベースに直接反映(マイグレーション履歴を作らない) |
db:studio | prisma studio | ブラウザベースのデータ閲覧・編集 UI を起動 |
db:generate | prisma migrate dev | 開発用マイグレーション作成+適用+クライアント再生成 |
db:migrate | prisma migrate deploy | 本番環境向けに既存マイグレーションを適用 |
postinstallが設定されているため、pnpm install(またはnpm install/yarn)を実行するだけで Prisma クライアントが自動生成され、src/server/db.tsの import が解決されます。
データベースのシーディング
データベースのシーディング(訳註:データベース構築時にダミーデータや初期データを投入すること)は、開発を始める際にテストデータを素早く投入できる非常に便利な機能です。create-t3-app の公式ドキュメントに沿ったセットアップ手順は次のとおりです。
1.seed.tsを作成する
/prismaディレクトリにseed.tsファイルを作成します。
import { db } from "../src/server/db"; async function main() { const id = "cl9ebqhxk00003b600tymydho"; await db.example.upsert({ where: { id, }, create: { id, }, update: {}, }); } main() .then(async () => { await db.$disconnect(); }) .catch(async (e) => { console.error(e); await db.$disconnect(); process.exit(1); });このサンプルはupsertを使って指定 ID のレコードが存在すれば更新、なければ作成するという冪等(何度実行しても同じ結果)なシーディングです。最後にdb.$disconnect()を呼んで接続を閉じ、エラー時はprocess.exit(1)で異常終了させる、という定番の流れになっています。
なお、上の例のdb.exampleはあくまで雛形です。実際のプロジェクトでは、スキーマで定義したモデル名に合わせてください。現在のリポジトリの基本スキーマ(base.prisma)ではモデルはPostなので、db.post.upsert(...)のようになります。
2.package.jsonにシード設定を追加する
package.jsonのscriptsにdb-seedを追加し、prismaキーにシード実行コマンドを定義します。
{ "scripts": { "db-seed": "NODE_ENV=development prisma db seed" }, "prisma": { "seed": "tsx prisma/seed.ts" } }NODE_ENV=developmentを明示しているのは、src/server/db.tsのログ設定がNODE_ENVで切り替わるためです。prisma db seedコマンドがprisma.seedで指定されたコマンドを実行します。
3. TypeScript ランナーを導入する
シードスクリプトは TypeScript で書かれているため、実行できるランナーが必要です。create-t3-app が推奨するのはtsxです。esbuild ベースで非常に高速に動作し、ESM 設定(ts-nodeで必要になるような)が不要という利点があります。ts-nodeや他のランナーでも動作します。
pnpm add -D tsx4. 実行する
あとは次のコマンドを実行するだけです。
pnpm db-seednpmやyarnを使っている場合は、それぞれnpm run db-seed、yarn db-seedと読み替えてください。
まとめ
create-t3-app が生成する Prisma 構成は、単なる ORM の雛形ではなく、「Next.js 開発における実践的な設計」が織り込まれています。
- グローバルクライアントパターン(
src/server/db.ts)による開発時の接続リーク防止 - 環境別のログレベル(開発時は
query/error/warn、本番はerrorのみ) - tRPC コンテキスト経由の
db公開による各ファイルでの個別 import 回避 - NextAuth.js 連携モデルの自動生成と MySQL 向け
@db.Textの自動有効化 - PlanetScale ドライバアダプタへの透過的な切り替え
postinstall・db:push・db:studio・db:generate・db:migrateという整備済み npm スクリプト
スキーマファイルは cli/template/extras/prisma/schema に、クライアント実装は cli/template/extras/src/server/db に、インストール処理は cli/src/installers/prisma.ts にそれぞれ置かれているため、興味があればぜひ読み進めてみてください。また、環境変数まわりは envVars.ts と src/env.js を、tRPC との連携は tRPC のドキュメント を参照すると、より全体像を把握できます。
関連する公式リソースとしては、Prisma 公式ドキュメント、Prisma GitHub リポジトリ、Prisma Migrate プレイグラウンド、NextAuth.js の Prisma アダプタ解説、PlanetScale 接続ガイドなどが役立ちます。いずれも Prisma のスキーマ記法の詳細やマイグレーションの応用手法を学ぶ際に参照してください。
- 开发工具
- CLI
- 代码生成
【免费下载链接】create-t3-app
The best way to start a full-stack, typesafe Next.js app
相关推荐
モデルのパラメータ解説:voice-changerにおける各設定の意味と影響
モデルのパラメータ解説:voice changerにおける各設定の意味と影響 1. はじめに voice changerはリアルタイムで音声を変換するツールであ
人工智能语音模型推理服务深度学习蓝鲸PaaS前端webfe开发指南:Vue.js单页应用快速本地启动与调试完整教程
蓝鲸PaaS前端webfe开发指南:Vue.js单页应用快速本地启动与调试完整教程 📌 文章概要 :蓝鲸智云 PaaS 平台(BlueKing PaaS)是一
后端云原生微服务前端企业应用开发者门户プロジェクトレベル CLAUDE.md 実践ガイド:ECC リポジトリに学ぶエージェント向け開発規約の設計とプロンプト防御
プロジェクトレベル CLAUDE.md 実践ガイド:ECC リポジトリに学ぶエージェント向け開発規約の設計とプロンプト防御 プロジェクトレベル CLAUDE.m
人工智能AI 技能AI 插件AI 评测Agent 评测MCP Clients开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考