Docs of Jace-Lab

Prisma

Drizzle에 이어 Prisma를 활용한 구축 가이드입니다. Prisma는 Drizzle과 달리 **선언적 스키마(schema.prisma)**와 코드 생성(Code Generation) 방식에 기반하고 있어, 대규모 프로젝트에서 타입 안정성이 매우 강력하다는 장점이 있습니다.

Jace님의 Supabase 및 모노레포 환경을 고려한 실전 가이드입니다.


1. 설치 (Installation)

Prisma는 CLI 도구와 런타임 클라이언트로 구성됩니다.

# 1. 개발 도구 설치
pnpm add -D prisma

# 2. 클라이언트 패키지 설치
pnpm add @prisma/client

2. 초기 설정 및 스키마 정의 (Setup)

Prisma의 핵심은 schema.prisma 파일입니다.

# 초기화 (prisma/schema.prisma 파일 생성)
npx prisma init

prisma/schema.prisma 작성 예시

Supabase를 사용하신다면 **Connection Pooling(6543)**과 **Direct Connection(5432)**을 명시적으로 구분하는 것이 필수입니다.

datasource db {
  provider  = "postgresql"
  // 실서비스용 (Transaction Pooler - 6543)
  url       = env("DATABASE_URL")
  // 마이그레이션용 (Direct Connection - 5432)
  directUrl = env("DIRECT_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id            String    @id @default(uuid())
  email         String    @unique
  name          String?
  isPremium     Boolean   @default(false)
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
  sessions      Session[]
}

model Session {
  id        String   @id @default(uuid())
  userId    String
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  expiresAt DateTime
}

3. 워크플로우 (Workflow)

Prisma는 스키마 수정 후 두 가지 명령어를 가장 많이 사용합니다.

A. prisma db push (개발용)

Drizzle의 push와 유사하게, 마이그레이션 파일 없이 즉시 DB에 반영합니다.

dotenv -e ../../.env -e .env -- npx prisma db push

B. prisma migrate dev (운영/기록용)

SQL 파일을 생성하고 DB에 적용합니다. 변경 이력을 추적할 때 사용합니다.

dotenv -e ../../.env -e .env -- npx prisma migrate dev --name init

4. 클라이언트 생성 및 연결 (Client)

Prisma는 스키마가 바뀔 때마다 클라이언트를 새로 생성(Generate)해야 합니다.

npx prisma generate

DB 연결 코드 (db.ts)

import { PrismaClient } from '@prisma/client'

// 개발 환경에서 Hot Reload 시 연결이 너무 많아지는 것을 방지
const globalForPrisma = global as unknown as { prisma: PrismaClient }

export const prisma = globalForPrisma.prisma || new PrismaClient({
  log: ['query'],
})

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

5. CRUD 사용법 (Usage)

Prisma는 자동 완성 기능이 매우 강력합니다.

데이터 삽입 (Create)

const newUser = await prisma.user.create({
  data: {
    email: 'jace@example.com',
    name: 'Jace',
    sessions: {
      create: { expiresAt: new Date(Date.now() + 3600000) }
    }
  }
})

데이터 조회 (Read)

const users = await prisma.user.findMany({
  where: { isPremium: true },
  include: { sessions: true } // 관계된 데이터 함께 가져오기
})

데이터 수정/삭제 (Update/Delete)

await prisma.user.update({
  where: { email: 'jace@example.com' },
  data: { isPremium: true }
})

6. 실전 팁 (Best Practices for Jace)

1. Supabase 포트 이슈 대응 Prisma에서도 아까 겪으신 6543 포트 이슈가 발생할 수 있습니다. migratedb push 명령어는 반드시 **directUrl (5432 포트)**을 사용하도록 설정하세요.

2. 모노레포에서의 Client 위치 모노레포에서 @prisma/client는 기본적으로 node_modules 안에 생성됩니다. 만약 공유 패키지에서 Prisma를 사용한다면, generator 설정에 output 경로를 지정하여 특정 위치에 클라이언트를 생성하는 것이 관리하기 편합니다.

3. Prisma Studio Neovim 외부에서 GUI로 데이터를 빠르게 확인하고 싶을 때 npx prisma studio를 실행해 보세요. 브라우저에서 편리하게 데이터를 조작할 수 있습니다.


Drizzle vs Prisma 간단 비교

  • Drizzle: SQL에 가깝고 가벼우며, 런타임 오버헤드가 거의 없습니다. Edge 환경(Cloudflare Workers 등)에 최적입니다.
  • Prisma: 스키마 관리가 엄격하고 선언적입니다. 관계 지향적인 쿼리를 작성할 때 생산성이 압도적입니다.

On this page