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
}