Prisma migrate

seongha_h·2025년 8월 16일
post-thumbnail

개요

데이터베이스 스키마 관리는 애플리케이션 개발에서 가장 중요하면서도 복잡한 작업 중 하나입니다.
Prisma Migrate는 이러한 복잡성을 해결하고 안전하고 예측 가능한 방식으로 데이터베이스 스키마를 관리할 수 있게 해주는 도구입니다.

데이터베이스 마이그레이션이란?

데이터베이스 마이그레이션은 데이터베이스 스키마의 구조를 수정하고 발전시키는 작업의 집합입니다.
마이그레이션을 통해 스키마를 한 상태에서 다른 상태로 안전하게 전환할 수 있습니다.

주요 작업 예시

  • 테이블 필드 추가/삭제/수정
  • 제약 조건 추가/제거
  • 인덱스 생성/삭제
  • 테이블 간 관계 설정

스키마 마이그레이션 패턴

데이터베이스 마이그레이션은 팀의 규모, 작업 방식, 기술 스택 등에 따라 다양한 방식으로 수행될 수 있습니다. 대표적인 마이그레이션 패턴은 크게 두 가지로 나뉩니다

  • Model/Entity-first: 애플리케이션의 코드(모델)를 기준으로 스키마를 정의하는 방식
  • Database-first: 데이터베이스 구조를 직접 정의하고 이를 기반으로 코드를 생성하는 방식

Prisma는 기본적으로 Model-first 방식에 초점을 맞추고 있지만, prisma db pull 등을 통해 Database-first 워크플로우도 지원합니다.

1. Model/Entity-first Migration

코드로 스키마 구조를 정의하고, 마이그레이션 도구가 데이터베이스와 동기화하기 위한 SQL을 자동 생성하는 방식입니다.

작동 방식
1. 애플리케이션 코드에서 모델 정의
2. 마이그레이션 도구가 변경사항 감지
3. SQL 마이그레이션 파일 자동 생성
4. 데이터베이스에 적용

2. Database-first Migration

SQL로 직접 데이터베이스 구조를 정의하고, 이를 기반으로 애플리케이션 코드를 생성하는 방식입니다.

작동 방식
1. SQL로 데이터베이스 스키마 직접 정의
2. 데이터베이스에 적용
3. 데이터베이스 구조를 기반으로 애플리케이션 코드 생성

마이그레이션 파일(SQL)은 애플리케이션 코드와 함께 버전 관리 시스템에서 관리되어야 합니다.

Prisma의 마이그레이션 상태 추적 방식

데이터베이스에 테이블을 추가하거나 index를 추가하는 등의 마이그레이션이 필요했습니다.

이 과정에서 다음 2가지 이유로 schema diff가 발생했습니다.

1. schema를 롤백했지만 db에는 남아있던 경우
테이블이나 인덱스를 추가한 후 schema.prisma를 롤백했지만 데이터베이스에는 변경사항이 남아 있는 경우, 스키마 차이(schema drift)가 발생하게 됩니다.
이는 코드와 실제 DB 상태가 일치하지 않음을 의미하며, Prisma는 이를 방지하고 해결하기 위한 명령어와 구조를 제공합니다.

2. 마이그레이션 파일의 해시값이 다른 경우
_prisma_migrations 테이블의 마이그레이션 목록 중 동일한 이름을 가진 항목이라 하더라도 해시값이 일치하지 않는 경우에도 schema diff가 발생할 수 있습니다. 이는 마이그레이션 파일을 수동으로 수정했거나, 버전 관리되지 않은 상태에서 마이그레이션이 진행되었을 때 발생할 수 있습니다.

Prisma의 스키마 상태 추적

Prisma는 4가지 구성 요소를 통해 데이터베이스 스키마 상태를 추적합니다
1. Prisma Schema: 애플리케이션의 스키마 정의 파일
2. Migrations History: prisma/migrations 폴더 내의 SQL 파일들 (코드 내)
3. Migrations Table: 데이터베이스의 _prisma_migrations 테이블
4. Database Schema: 실제 데이터베이스의 현재 상태

Prisma migration 명령어

1. prisma migrate dev (주의)

개발 환경에서 스키마 변경사항을 추적하고 적용하는 명령어입니다.

prisma migrate 는 shadow database 를 이용하여 스키마 drifty를 감지하고 새로운 migration을 생성합니다.
prisma migrate dev 는 schema drift 또는 마이그레이션 기록 충돌을 감지하면 데이터 베이스 재설정 (drop and recreate)을 통해 동기화 하라는 메세지가 표시됩니다.
→ 이는 데이터 베이스 초기화를 유발하므로 주의해야 합니다.

npx prisma migrate dev --name <migration-name>

동작 과정
1. Prisma 스키마 파일의 변경사항 감지
2. SQL 마이그레이션 파일 자동 생성
3. 데이터베이스에 마이그레이션 적용
4. _prisma_migrations 테이블 업데이트

⚠️ 주의: 개발 환경에서만 사용해야 합니다.
schema diff 가 있을 경우 DB데이터를 초기화 하겠냐고 물어보는 문구가 존재합니다.
이는 진짜 db를 삭제하는 것이므로 절대 사용하지 말아야 합니다.

2. --create-only 플래그

마이그레이션 파일을 생성만 하고 적용하지 않을 때 사용합니다.
이를 통해 실제로 수행될 마이그레이션 파일을 생성하고, db에 직접 적용하지는 않을 수 있습니다. 이를 통해 개발자가 검토하고 적용할 수 있습니다.
예를 들어 데이터를 손실하지 않고, 데이터베이스 확장 등을 발생시키지 않으면서 column이름을 수정하는 등에 대해 사용됩니다.

npx prisma migrate dev --create-only

사용 사례

  • 컬럼 이름 변경 시 데이터 손실 방지
  • 커스텀 SQL 추가
  • 마이그레이션 검토 후 적용

3. prisma migrate diff

스키마 차이를 비교하고 SQL을 생성합니다.

npx prisma migrate diff \
  --from-schema-datamodel prisma/schema.prisma \
  --to-schema-datasource prisma/schema.prisma \
  --script

사용 사례

  • Schema drift 해결
  • 수동 변경사항 동기화
  • 마이그레이션 SQL 미리보기

1,2 에서 발생한 schema diff를 이 명령어를 통해 파악할 수 있습니다.

4. prisma migrate deploy

프로덕션 환경에서 마이그레이션을 적용하는 명령어입니다.
prisma migrate deploy 명령어를 이용하면 개발환경의 마이그레이션 기록과 데이터 베이스를 동기화 할 수 있습니다.
schema diff 를 판단하는 정합성 검사를 수행하지 않습니다. 따라서 오류가 발생할 수 있습니다.

npx prisma migrate deploy

동작 과정
1. _prisma_migrations 테이블과 /prisma/migrations 비교
2. 미적용 마이그레이션 순차적 적용
3. _prisma_migrations 테이블 업데이트

💡 베스트 프랙티스: CI/CD 파이프라인에서 자동화하여 실행

5. prisma db push

마이그레이션 히스토리 없이 스키마를 직접 적용합니다.
마이그레이션 기록(/migrations) 이 없는 경우 prisma db push 를 이용해야 합니다.
이 경우에는 database 스키마와 데이터 등이 파괴될 수 있으므로 주의가 필요합니다.
(drop and re-create 동작이 됩니다)

npx prisma db push

⚠️ 위험: 데이터 손실 가능성이 있으므로 프로덕션에서는 사용하지 마세요.

Schema drift 해결 방안

schema drift는 예상 데이터베이스 스키마가 마이그레이션 기록과 다를 경우 발생합니다.
Prisma 스키마 및 Prisma/Migrations를 업데이트하지 않고 데이터베이스 스키마를 수동으로 업데이트 할 때 발생할 수 있습니다.

1. prisma migrate diff로 drift 확인 및 SQL 생성

migrate diff는 DB와 Prisma 스키마의 차이를 비교하고 SQL을 생성합니다.
변경 내용을 되돌리거나, 반대로 현재 DB 상태에 맞춰 schema.prisma를 수정할 수 있습니다.

또한, migrate diff 를 사용하여 SQL을 생성할 수도 있습니다.

npx prisma migrate diff \
  --from-migrations ./prisma/migrations \
  --to-schema-datasource ./prisma/schema.prisma \
  --script > sync.sql
  • 데이터베이스 스키마 변경사항을 현재 prisma.schema 와 동기화 하고 싶을 경우
  • 애플리케이션의 prisma.schema/migrations 에서의 누락된 변경 사항들을 DB에 반영하고 싶을 때

2. 수동 SQL 실행 후 해결

변경 사항을 직접 DB에 실행한 뒤 해당 migration 파일이 "적용되었음"을 명시하여 diff 가 발생하지 않도록 합니다.
SQL은 실행되지 않습니다.

npx prisma migrate resolve --applied <migration-name>

파일 구조

prisma/
└── migrations/
├── 20240101120000_init/
│ └── migration.sql
├── 20240102130000_add_user_fields/
│ └── migration.sql
└── migration_lock.toml

_prisma_migrations 테이블

  • id: 마이그레이션 고유 식별자
  • checksum: 마이그레이션 파일의 해시값
  • applied_at: 적용 시간
  • migration_name: 마이그레이션 이름

💡 중요: Prisma는 마이그레이션 내용이 아닌 해시값으로 변경을 감지합니다.

마무리

Prisma Migrate는 강력하면서도 안전한 데이터베이스 마이그레이션 도구입니다. 올바른 사용법과
베스트 프랙티스를 따른다면, 복잡한 스키마 변경도 안전하게 관리할 수 있습니다.

핵심 요약

profile
https://github.com/Fixtar

0개의 댓글