Prisma Migrate 운영 전략

Prisma Migrate란?

Prisma Migrate는 schema.prisma 파일의 변경사항을 SQL 마이그레이션으로 변환하고, 버전 관리하는 도구다. 단순한 스키마 동기화를 넘어 프로덕션 안전한 마이그레이션, 시딩 전략, CI/CD 통합까지 다룬다.

1. 마이그레이션 기본 워크플로

# 개발 환경: 스키마 변경 → 마이그레이션 생성 + 적용
npx prisma migrate dev --name add_user_role

# 프로덕션: 기존 마이그레이션 파일만 적용
npx prisma migrate deploy

# 마이그레이션 상태 확인
npx prisma migrate status

# 마이그레이션 리셋 (개발 전용 — 데이터 삭제됨)
npx prisma migrate reset

migrate dev는 마이그레이션 파일 생성 + shadow DB 검증 + 적용을 한번에 수행한다. migrate deploy는 프로덕션에서 pending 마이그레이션만 순차 적용한다.

명령 환경 동작
migrate dev 개발 생성 + shadow DB + 적용 + seed
migrate deploy 프로덕션 pending 마이그레이션 순차 적용
migrate reset 개발 DB 삭제 + 전체 재적용 + seed
migrate status 공통 적용/미적용 상태 확인
db push 프로토타입 파일 없이 스키마 바로 반영

2. 마이그레이션 파일 구조

prisma/
  migrations/
    20260301_init/
      migration.sql
    20260301_add_user_role/
      migration.sql
    migration_lock.toml    # DB 엔진 잠금 (mysql, postgresql 등)
  schema.prisma
  seed.ts

각 마이그레이션은 타임스탬프 디렉토리에 migration.sql이 포함된다. 이 SQL을 직접 수정할 수 있어 Prisma가 자동 생성하지 못하는 작업(데이터 변환, 인덱스 커스텀)을 추가할 수 있다.

3. 커스텀 마이그레이션: 데이터 변환

컬럼 추가와 함께 기존 데이터를 변환해야 하는 경우, 자동 생성된 SQL을 수정한다.

# 빈 마이그레이션 생성 (--create-only로 적용하지 않음)
npx prisma migrate dev --name split_full_name --create-only

생성된 migration.sql을 수정:

-- 1. 새 컬럼 추가
ALTER TABLE "User" ADD COLUMN "first_name" TEXT;
ALTER TABLE "User" ADD COLUMN "last_name" TEXT;

-- 2. 기존 데이터 변환
UPDATE "User" SET
  "first_name" = split_part("full_name", ' ', 1),
  "last_name" = split_part("full_name", ' ', 2)
WHERE "full_name" IS NOT NULL;

-- 3. NOT NULL 제약 추가
ALTER TABLE "User" ALTER COLUMN "first_name" SET NOT NULL;
ALTER TABLE "User" ALTER COLUMN "last_name" SET NOT NULL;

-- 4. 이전 컬럼 삭제
ALTER TABLE "User" DROP COLUMN "full_name";
# 수정 후 적용
npx prisma migrate dev

4. Baseline: 기존 DB에 Prisma 도입

이미 운영 중인 DB에 Prisma Migrate를 처음 도입할 때 baseline을 설정한다.

# 1. 현재 DB 스키마를 Prisma로 가져오기
npx prisma db pull

# 2. 초기 마이그레이션 생성 (적용하지 않음)
npx prisma migrate dev --name init --create-only

# 3. 이미 적용된 것으로 마킹 (baseline)
npx prisma migrate resolve --applied 20260301_init

# 4. 이후부터 정상적인 마이그레이션 워크플로 사용
npx prisma migrate dev --name add_new_feature

migrate resolve --applied는 마이그레이션을 실행하지 않고 “이미 적용됨”으로 기록한다. 프로덕션 DB를 건드리지 않으면서 Prisma의 마이그레이션 히스토리를 동기화한다.

5. Seed 전략

prisma/seed.ts로 초기 데이터를 관리한다.

// prisma/seed.ts
import { PrismaClient } from '@prisma/client';
import { hash } from 'bcrypt';

const prisma = new PrismaClient();

async function main() {
  // Upsert: 멱등성 보장 — 여러 번 실행해도 안전
  const admin = await prisma.user.upsert({
    where: { email: 'admin@example.com' },
    update: {},
    create: {
      email: 'admin@example.com',
      name: 'Admin',
      password: await hash('admin1234', 10),
      role: 'ADMIN',
    },
  });

  // 카테고리 시드
  const categories = ['Backend', 'Frontend', 'DevOps', 'Database'];
  for (const name of categories) {
    await prisma.category.upsert({
      where: { name },
      update: {},
      create: { name, slug: name.toLowerCase() },
    });
  }

  // 개발용 대량 데이터
  if (process.env.NODE_ENV !== 'production') {
    await prisma.post.createMany({
      data: Array.from({ length: 100 }, (_, i) => ({
        title: `Test Post ${i + 1}`,
        content: `Content for post ${i + 1}`,
        authorId: admin.id,
        categoryId: 1,
      })),
      skipDuplicates: true,
    });
  }

  console.log('✅ Seed completed');
}

main()
  .catch(console.error)
  .finally(() => prisma.$disconnect());
// package.json
{
  "prisma": {
    "seed": "ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts"
  }
}

// 실행
npx prisma db seed

upsert를 사용하면 seed를 여러 번 실행해도 데이터가 중복되지 않는다. migrate resetmigrate dev 실행 시 seed가 자동으로 호출된다.

6. CI/CD 파이프라인 통합

# GitHub Actions 예시
name: Deploy
on:
  push:
    branches: [main]

jobs:
  migrate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - run: npm ci

      - name: Check migration status
        run: npx prisma migrate status
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

      - name: Apply migrations
        run: npx prisma migrate deploy
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

      - name: Generate client
        run: npx prisma generate

      - name: Deploy app
        run: npm run deploy

⚠️ 주의: CI에서는 반드시 migrate deploy를 사용한다. migrate dev는 shadow DB를 생성하므로 프로덕션 환경에서 절대 사용하지 않는다.

7. 롤백 전략

Prisma Migrate는 자동 롤백을 지원하지 않는다. 수동으로 역방향 마이그레이션을 작성해야 한다.

# 1. 실패한 마이그레이션 표시
npx prisma migrate resolve --rolled-back 20260301_add_user_role

# 2. 역방향 SQL 작성 후 새 마이그레이션으로 적용
npx prisma migrate dev --name rollback_user_role --create-only
# → migration.sql에 DROP COLUMN 등 역방향 SQL 작성
npx prisma migrate dev

프로덕션에서는 확장 전용(expand-only) 마이그레이션을 권장한다: 컬럼 삭제 대신 nullable로 변경, 테이블 삭제 대신 이름 변경 후 다음 릴리즈에서 삭제. Prisma의 기본 쿼리 패턴은 Prisma ORM 실전 심화 글을 참고하자.

마무리

Prisma Migrate는 선언적 스키마에서 SQL 마이그레이션을 자동 생성하는 강력한 도구다. 커스텀 SQL 수정으로 데이터 변환을 처리하고, baseline으로 기존 DB에 안전하게 도입하며, CI/CD 파이프라인에서 migrate deploy로 자동화하는 것이 프로덕션 운영의 핵심이다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux