Skip to Content

PrismaでDBを操作する

このページで学ぶこと

  • Prisma とは何かがわかる
  • Prisma スキーマを定義してDBにテーブルを作れる
  • Prisma Client でデータを取得・作成できる

Prisma とは

Prisma は JavaScript/TypeScript 向けの ORM(Object-Relational Mapper) です。

SQLを直接書く代わりに、JavaScriptのコードでDBを操作できます。

Prisma (ORM) の利点(簡潔版)

  • SQLを毎回手書きしなくてよいので、開発スピードが上がる
  • 型付きで補完が効くため、カラム名のミスに気づきやすい
  • スキーマ変更をマイグレーションとして管理しやすい
// ❌ 素のSQLだとこう書く
const result = await db.query('SELECT * FROM todos WHERE user_id = $1', [userId])
 
// ✅ Prismaだとこう書ける
const todos = await prisma.todo.findMany({
  where: { userId: userId }
})
javascript

セットアップ

ステップ1: Prisma をインストール

npm install prisma --save-dev
npm install @prisma/client @prisma/adapter-pg pg dotenv
npx prisma init
bash

prisma/schema.prisma.env が作成されます。

Prisma 7 では、CLI が使う接続先を prisma.config.ts で管理するのが基本です。
プロジェクトルートに prisma.config.ts を作成しましょう。

// prisma.config.ts
import 'dotenv/config' // .env を読み込む
import { defineConfig, env } from 'prisma/config'
 
export default defineConfig({
  schema: 'prisma/schema.prisma', // Prismaスキーマの場所
  datasource: {
    url: env('DATABASE_URL'), // CLIが使うDB接続文字列
  },
})
typescript

ステップ2: schema.prisma を編集する

前のページで設計した構造をPrismaスキーマとして書きます。
prisma/schema.prisma を開いて編集する。

// prisma/schema.prisma
 
generator client {
  provider = "prisma-client"
  output   = "../generated/prisma" // Prisma Client の生成先(Prisma 7 では output が必須)
}
 
datasource db {
  provider = "postgresql"
}
 
model User {
  id        Int      @id @default(autoincrement()) // 主キーで自動採番(1, 2, 3...)される
  name      String
  email     String   @unique // ユニーク制約(同じ値は入れられない)
  todos     Todo[] // 1対多のリレーション(Userは複数のTodoを持てる)
  createdAt DateTime @default(now()) @map("created_at") // デフォルト値を現在時刻にする & カラム名は created_at にする
 
  @@map("users")  // テーブル名を "users" にする
}
 
model Todo {
  id          Int      @id @default(autoincrement())
  title       String
  completed   Boolean  @default(false)
  userId      Int      @map("user_id")
  user        User     @relation(fields: [userId], references: [id])
  createdAt   DateTime @default(now()) @map("created_at")
 
  @@map("todos")
}
prisma

ステップ3: DBにテーブルを作成する(マイグレーション)

npx prisma migrate dev --name init
npx prisma generate
bash

コマンドの意味は次のとおりです。

  • prisma migrate dev: 開発環境のDBにスキーマ変更を反映する
  • prisma generate: Prisma Client を生成する(Prisma 7 では明示実行)
  • --name init: この変更セット(マイグレーション)に init という名前を付ける

✅ Your database is now in sync with your schema. と表示されれば成功です。
Supabase のダッシュボード(Table Editor)を開くと userstodos テーブルができているはずです。

マイグレーションとは?
スキーマの変更をDBに反映させることです。
migrate dev は開発環境用で、スキーマを変更するたびに実行します。
Prisma 7 では、変更後に prisma generate も忘れず実行しましょう。

ステップ4: Prisma Client を初期化する

lib/prisma.js を作成する。

// lib/prisma.js
import { PrismaClient } from '../generated/prisma/client.js' // ESM では拡張子 .js まで書く
import { PrismaPg } from '@prisma/adapter-pg'
 
// 開発環境での重複インスタンス防止
const globalForPrisma = globalThis
 
// PostgreSQL用のアダプターを作る(Prisma 7 では adapter が必須)
const adapter = new PrismaPg({
  connectionString: process.env.DATABASE_URL,
})
 
// ?? は「左が null / undefined のときだけ右を使う」演算子
export const prisma = globalForPrisma.prisma ?? new PrismaClient({ adapter })
 
// NODE_ENV は実行環境を表す環境変数(development / production など)
// 開発時だけ global に保持して、ホットリロード時の多重接続を防ぐ
if (process.env.NODE_ENV !== 'production') {
  globalForPrisma.prisma = prisma
}
javascript

以下のコマンドを実行して、Prisma Client を生成しましょう。

npx prisma generate
bash

スキーマを変更したら、migrate dev のあとに generate までを1セットで実行するのが安全です。


Prisma Client の基本操作

データを取得する

import { prisma } from '../lib/prisma'
 
// 全件取得
const todos = await prisma.todo.findMany()
 
// 条件付き取得
const myTodos = await prisma.todo.findMany({
  where: { userId: 1 } // この章では userId は Int で扱う
})
 
// 1件取得
const todo = await prisma.todo.findUnique({
  where: { id: 1 }
})
 
// 関連データも一緒に取得(JOIN)
// JOIN = 複数テーブルを結合してまとめて取るイメージ
const user = await prisma.user.findUnique({
  where: { id: 1 },
  include: { todos: true }  // userとそのtodosを取得
})
javascript

データを作成する

const newTodo = await prisma.todo.create({
  data: {
    title: '牛乳を買う',
    userId: 1,
  }
})
javascript

データを更新する

const updated = await prisma.todo.update({
  where: { id: 1 },
  data: { completed: true }
})
javascript

データを削除する

await prisma.todo.delete({
  where: { id: 1 }
})
javascript

API Route と組み合わせる

app/api/todos/route.js をPrismaを使うように書き換えましょう。

// app/api/todos/route.js
import { NextResponse } from 'next/server'
import { prisma } from '../../../lib/prisma'
 
export async function GET() {
  const todos = await prisma.todo.findMany({
    orderBy: { createdAt: 'desc' }  // 新しい順に並べる
  })
  return NextResponse.json(todos)
}
 
export async function POST(request) {
  const body = await request.json()
 
  if (!body.title) {
    return NextResponse.json({ error: 'titleは必須です' }, { status: 400 })
  }
 
  const todo = await prisma.todo.create({
    data: {
      title: body.title,
      userId: 1,  // TODO: 認証後は実際のユーザーID(文字列のUUID)を使う
    }
  })
 
  return NextResponse.json(todo, { status: 201 })
}
javascript

確認しよう

  • npx prisma init でPrismaを初期化した
  • prisma.config.ts を作成して DATABASE_URL を設定した
  • schema.prisma にモデルを定義した
  • npx prisma migrate dev でテーブルを作成した
  • npx prisma generate で Prisma Client を生成した
  • Supabaseダッシュボードでテーブルができていることを確認した
  • prisma.todo.findMany() でデータを取得できた

AIに聞いてみよう

「Prismaのスキーマを変更したとき、既存のデータを保ちながらマイグレーションするにはどうしますか?」


次のステップ

CRUD操作を実装しよう

Last updated on