Prismaの詳細ガイド

Next.js、Vercel、Supabaseとの連携 - 2025年3月13日
📊 📚 🔍
📌 Prismaの基本概念と特徴

PrismaはNode.jsとTypeScript用のORMで、型安全なデータベースアクセスが強みです。

ORMとは?データベースとオブジェクト指向プログラミング言語の間の「通訳」のようなもの!
  • Prisma Client: データベース操作用クライアントライブラリ
  • Prisma Migrate: マイグレーション用ツール
  • Prisma Studio: データベース視覚操作GUI
  • PostgreSQL、MySQL、SQLite、MongoDBなど様々なDBをサポート!
    🚀 Prismaのセットアップと初期化

    まずはパッケージのインストールから始めましょう

    npm install prisma --save-dev
    npm install @prisma/client

    または、Yarnを使用する場合:

    yarn add prisma --dev
    yarn add @prisma/client

    次に、Prismaを初期化します

    npx prisma init

    初期化後に生成されるファイル:

    📄 prisma/schema.prisma: スキーマ定義ファイル

    📄 .env: 環境変数ファイル

    📝 Prismaスキーマの書き方

    schema.prismaファイルでデータモデルを定義します

    generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") directUrl = env("DIRECT_URL") // Supabase用 } // ユーザーモデルの定義 model User { id Int @id @default(autoincrement()) email String @unique name String? posts Post[] } // 投稿モデルの定義 model Post { id Int @id @default(autoincrement()) title String content String? published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) authorId Int }
  • @id: プライマリキーを指定
  • @default: デフォルト値を設定
  • @unique: ユニーク制約
  • @relation: リレーションシップの定義
  • ⌨️ Prismaの主要コマンド
    コマンド一覧を覚えておくと作業が捗ります!

    スキーマ関連:

    npx prisma init
    npx prisma format
    npx prisma validate

    マイグレーション関連:

    npx prisma migrate dev --name 名前
    npx prisma migrate deploy
    npx prisma db push
    npx prisma db pull

    データ操作・管理:

    npx prisma db seed
    npx prisma studio
    npx prisma generate
    🔄 Next.jsとPrismaの連携

    Next.jsでPrisma Clientを使用する際はシングルトンパターンを採用します

    ホットリロードによる接続数の問題を避けるため!

    // lib/prisma.ts import { PrismaClient } from '@prisma/client' const globalForPrisma = global as unknown as { prisma: PrismaClient } export const prisma = globalForPrisma.prisma || new PrismaClient() if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

    App Router(Server Components)での使用例:

    // app/users/page.tsx import { prisma } from '@/lib/prisma' export default async function UsersPage() { const users = await prisma.user.findMany({ include: { posts: true, }, }) return (

    ユーザー一覧

    {users.map(user => (

    {user.name}

    投稿数: {user.posts.length}

    ))}
    ) }
    🔌 SupabaseとPrismaの連携

    Supabaseを使用する場合は接続モードに注意が必要です

    環境変数の設定:

    🔹 DATABASE_URL: アプリケーションのクエリ用(ポート6543)

    🔹 DIRECT_URL: マイグレーション用(ポート5432)

    # トランザクションモード用(ポート6543) DATABASE_URL="postgres://[user].[project]:[pass]@aws-0-[region].pooler.supabase.com:6543/[db]?pgbouncer=true&connection_limit=1" # セッションモード用(ポート5432) DIRECT_URL="postgres://[user].[project]:[pass]@aws-0-[region].pooler.supabase.com:5432/[db]"
    schema.prismaファイルにもdirectUrlを追加する必要があります!
    datasource db { provider = "postgresql" url = env("DATABASE_URL") directUrl = env("DIRECT_URL") }
    🛠️ 環境別の設定管理
    開発環境と本番環境で設定を分けて管理しましょう!

    ローカル開発環境の設定:

    # ローカル環境用(.env.local) DATABASE_URL="postgresql://postgres:postgres@127.0.0.1:5432/postgres" DIRECT_URL="postgresql://postgres:postgres@127.0.0.1:5432/postgres"

    本番環境(Vercel + Supabase)の設定:

    # 本番環境用 DATABASE_URL="postgres://[user].[project]:[pass]@aws-0-[region].pooler.supabase.com:6543/[db]?pgbouncer=true&connection_limit=1" DIRECT_URL="postgres://[user].[project]:[pass]@aws-0-[region].pooler.supabase.com:5432/[db]"
    環境別に.envファイルを作成し、実行時に指定できます
    npm run dev -- --env-file=.env.dev
    npm run prod -- --env-file=.env.prod
    🚢 Vercelへのデプロイ

    VercelにNext.js + Prismaのプロジェクトをデプロイする際の設定

    ビルドコマンドの修正(package.json):

    { "scripts": { "dev": "next dev", "build": "prisma generate && next build", "start": "next start", "lint": "next lint", "postinstall": "prisma generate" } }
  • Vercelダッシュボードから新規プロジェクトを作成
  • GitHubリポジトリを連携
  • 環境変数でDATABASE_URLDIRECT_URLを設定
  • 必要に応じてビルドコマンドをオーバーライド
  • npx prisma generate && next build
    💾 データベース操作

    Prisma Clientを使用したCRUD操作の例

    データの取得(Read):

    // 全件取得 const users = await prisma.user.findMany(); // 条件付き取得 const user = await prisma.user.findUnique({ where: { id: 1 }, }); // リレーション含めて取得 const userWithPosts = await prisma.user.findUnique({ where: { id: 1 }, include: { posts: true }, });

    データの作成(Create):

    // 単一レコード作成 const user = await prisma.user.create({ data: { name: "John Doe", email: "john@example.com", }, }); // リレーションを含めた作成 const userWithPost = await prisma.user.create({ data: { name: "Jane Doe", email: "jane@example.com", posts: { create: { title: "Hello World", content: "This is my first post", }, }, }, include: { posts: true, }, });

    データの更新と削除:

    // 更新 const updatedUser = await prisma.user.update({ where: { id: 1 }, data: { name: "Updated Name" }, }); // 削除 const deletedUser = await prisma.user.delete({ where: { id: 1 }, });
    🔄 トランザクション

    複数の操作を一つのトランザクションとして実行する方法

    トランザクションは「全て成功するか、全て失敗するか」を保証します!
    const result = await prisma.$transaction(async (tx) => { // ユーザーを作成 const user = await tx.user.create({ data: { name: "Transaction User", email: "tx@example.com", }, }); // 関連する投稿を作成 const post = await tx.post.create({ data: { title: "Transaction Post", content: "Created in a transaction", authorId: user.id, }, }); return { user, post }; });
    📊 マイグレーション管理

    マイグレーションの基本的な流れ:

  • schema.prismaファイルを編集してデータモデルを変更
  • マイグレーションを作成・適用
  • npx prisma migrate dev --name add_user_profile

    この操作によりprisma/migrationsディレクトリに新しいマイグレーションファイルが作成されます


    本番環境でのマイグレーション:

    本番環境では、既存のマイグレーションファイルを適用するだけ!
    npx prisma migrate deploy

    これは、CIパイプラインやデプロイスクリプトに組み込むことができます

    🔧 トラブルシューティング
    重要

    よく発生する問題とその解決策

    マイグレーションが応答しない問題

    🔹 症状: npx prisma migrate devが応答しない

    🔹 原因: DIRECT_URLのポート番号が間違っている可能性

    🔹 解決策: ポート番号を5432に変更

    PrismaClientInitializationError

    🔹 症状: アプリケーション実行時にエラー発生

    🔹 原因: 環境変数の設定ミスや接続情報の誤り

    🔹 解決策: Vercelの環境変数設定を確認、schema.prismadirectUrlが設定されているか確認

    Supabaseとの接続エラー

    🔹 症状: ローカルでは動作するが、デプロイ後に接続エラー

    🔹 解決策: schema.prismadirectUrlを追加、環境変数にDIRECT_URLを追加