본문으로 건너뛰기
Advertisement

15.1 Prisma 소개 — TypeScript ORM의 표준

Prisma란?

Prisma는 TypeScript 기반의 차세대 ORM(Object-Relational Mapper)입니다. 스키마 파일로 데이터 모델을 정의하면 타입 안전한 클라이언트를 자동 생성합니다.

Prisma 구성:
- Prisma Schema: 데이터 모델 정의 (.prisma 파일)
- Prisma Client: 자동 생성된 타입 안전 쿼리 빌더
- Prisma Migrate: 스키마 기반 DB 마이그레이션
- Prisma Studio: 데이터 시각화 GUI

설치 및 초기화

npm install prisma @prisma/client
npx prisma init # prisma/schema.prisma 와 .env 생성

환경 변수 설정

# .env
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"

기본 스키마 작성

// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql" // mysql, sqlite, mongodb 등
url = env("DATABASE_URL")
}

model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
profile Profile?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
tags Tag[]
createdAt DateTime @default(now())
}

model Profile {
id Int @id @default(autoincrement())
bio String?
user User @relation(fields: [userId], references: [id])
userId Int @unique
}

model Tag {
id Int @id @default(autoincrement())
name String @unique
posts Post[]
}

마이그레이션 실행

# 마이그레이션 생성 및 적용
npx prisma migrate dev --name init

# 프로덕션 마이그레이션 적용
npx prisma migrate deploy

# Prisma Client 재생성 (스키마 변경 후)
npx prisma generate

# Prisma Studio 실행
npx prisma studio

Prisma Client 기본 사용

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
// 연결은 자동 관리됨

// 사용자 생성
const user = await prisma.user.create({
data: {
email: 'alice@example.com',
name: 'Alice',
},
})
console.log(user)
// { id: 1, email: 'alice@example.com', name: 'Alice', ... }
}

main()
.catch(console.error)
.finally(async () => {
await prisma.$disconnect()
})

필드 타입 참조

model Example {
// 기본 타입
id Int @id @default(autoincrement())
uuid String @id @default(uuid())
cuid String @id @default(cuid())

// 스칼라 타입
name String
age Int
score Float
isActive Boolean @default(true)
data Json
bytes Bytes
createdAt DateTime @default(now())

// 선택적 필드
bio String?

// 기본값
role Role @default(USER)
count Int @default(0)

// 인덱스
@@index([name])
@@unique([email, tenantId])
}

enum Role {
ADMIN
USER
GUEST
}

고수 팁

Prisma Client 싱글톤 패턴

// lib/prisma.ts
import { PrismaClient } from '@prisma/client'

const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined
}

export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
})

// 개발 환경에서 핫 리로드 시 연결 누수 방지
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma
}

Prisma Accelerate (엣지 캐싱)

import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'

const prisma = new PrismaClient().$extends(withAccelerate())

// 캐시 TTL 설정
const users = await prisma.user.findMany({
cacheStrategy: { ttl: 60 }, // 60초 캐시
})
Advertisement