본문으로 건너뛰기
Advertisement

15.5 Prisma 마이그레이션 — 스키마 관리와 시딩

마이그레이션 워크플로우

개발 흐름:
1. schema.prisma 수정
2. npx prisma migrate dev → 마이그레이션 파일 생성 + DB 적용
3. npx prisma generate → Prisma Client 재생성 (자동)
4. git에 마이그레이션 파일 커밋

배포 흐름:
1. git pull (마이그레이션 파일 포함)
2. npx prisma migrate deploy → 미적용 마이그레이션만 순서대로 실행

마이그레이션 명령어

# 개발 환경 — 마이그레이션 생성 및 적용
npx prisma migrate dev --name add-user-avatar

# 마이그레이션 히스토리 확인
npx prisma migrate status

# 프로덕션 배포 (CI/CD에서 사용)
npx prisma migrate deploy

# 마이그레이션 초기화 (개발 DB 리셋)
npx prisma migrate reset

# 특정 마이그레이션으로 되돌리기 (미지원 — 수동 SQL 필요)

생성된 마이그레이션 파일 예시

-- prisma/migrations/20240115000000_add_user_avatar/migration.sql

-- AlterTable
ALTER TABLE "User" ADD COLUMN "avatar" TEXT;
ALTER TABLE "User" ADD COLUMN "avatarUpdatedAt" TIMESTAMP(3);

스키마 변경 패턴

컬럼 추가 (안전)

model User {
// 기존 필드들...
avatar String? // nullable로 추가하면 기존 데이터 영향 없음
bio String @default("") // 기본값 설정
}

컬럼 이름 변경

model User {
// firstName → name으로 변경
// 직접 이름 변경 시 데이터 손실! @map 사용
name String @map("firstName") // DB 컬럼명은 유지, Prisma 접근명만 변경
}

컬럼 삭제 (주의)

// 1단계: 애플리케이션 코드에서 해당 필드 참조 제거
// 2단계: nullable로 변경 후 배포
// 3단계: 실제 컬럼 삭제 마이그레이션 실행

테이블 이름 변경

model Article {
@@map("Post") // DB 테이블명은 "Post", Prisma 모델명은 "Article"
}

데이터 시딩 (Seeding)

// prisma/seed.ts
import { PrismaClient } from '@prisma/client'
import * as bcrypt from 'bcrypt'

const prisma = new PrismaClient()

async function main() {
// 기존 데이터 정리 (선택적)
await prisma.post.deleteMany()
await prisma.user.deleteMany()

// 관리자 계정 생성
const admin = await prisma.user.create({
data: {
email: 'admin@example.com',
name: 'Admin',
password: await bcrypt.hash('adminpassword', 10),
role: 'ADMIN',
},
})

// 일반 사용자 및 게시글 생성
const users = await Promise.all(
Array.from({ length: 5 }, (_, i) =>
prisma.user.create({
data: {
email: `user${i + 1}@example.com`,
name: `User ${i + 1}`,
password: await bcrypt.hash('password', 10),
posts: {
create: Array.from({ length: 3 }, (_, j) => ({
title: `User ${i + 1}의 글 ${j + 1}`,
content: `내용 ${j + 1}`,
published: j < 2, // 처음 2개만 게시
})),
},
},
})
)
)

console.log(`생성된 사용자: ${users.length}`)
}

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

package.json에 시드 설정

{
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"devDependencies": {
"tsx": "^4.0.0"
}
}
# 시드 실행
npx prisma db seed

# 마이그레이션 리셋 + 시드 자동 실행
npx prisma migrate reset

환경별 데이터베이스 설정

# .env (개발 환경)
DATABASE_URL="postgresql://user:password@localhost:5432/myapp_dev"

# .env.test (테스트 환경)
DATABASE_URL="postgresql://user:password@localhost:5432/myapp_test"

# .env.production (프로덕션)
DATABASE_URL="postgresql://user:password@prod-db:5432/myapp_prod?connection_limit=10&pool_timeout=20"

고수 팁

스키마 검증 및 포맷

# 스키마 문법 검사
npx prisma validate

# 스키마 파일 포맷팅
npx prisma format

# ERD 다이어그램 생성 (prisma-erd-generator 설치 필요)
npx prisma generate # ERD.svg 자동 생성

CI/CD 파이프라인 설정

# .github/workflows/deploy.yml
jobs:
deploy:
steps:
- name: Apply migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}

- name: Generate Prisma Client
run: npx prisma generate

Prisma Schema 분리 (대형 프로젝트)

// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["prismaSchemaFolder"]
}

// prisma/schema/user.prisma — 모델별 파일 분리 가능 (Preview 기능)
model User {
id Int @id
email String @unique
}
Advertisement