runlot

마이그레이션

번호가 있는 SQL 파일을 순서대로 적용하고, 적용 이력은 데이터베이스 테이블에 기록합니다.

my-app/
  migrations/
    0001_init.sql
    0002_add_posts.sql
runlot pg migrate
0001_init
0002_add_posts

적용할 마이그레이션이 없으면 CLI가 이를 알려 줍니다.

파일 이름 규칙

파일 이름은 NNNN_이름.sql 형식이어야 합니다. 번호는 양의 정수여야 합니다. 기본 디렉터리는 <프로젝트>/migrations이며, --migrations 옵션으로 변경할 수 있습니다.

적용 이력

적용한 마이그레이션은 데이터베이스의 다음 테이블에 기록됩니다.

CREATE TABLE IF NOT EXISTS schema_migrations (
  version    int  PRIMARY KEY,
  name       text NOT NULL,
  sha256     text NOT NULL,
  applied_at timestamptz NOT NULL DEFAULT now()
)

언제 어떤 마이그레이션이 적용됐는지 SQL로 바로 확인할 수 있습니다.

runlot pg execute -c "select version, name, applied_at from schema_migrations order by version"

파일 하나는 하나의 트랜잭션으로 적용합니다

각 파일의 DDL과 적용 이력 기록은 같은 트랜잭션에서 실행됩니다. 실행 중 오류가 발생하면 파일 내용과 이력이 함께 롤백되므로, 일부만 적용된 상태로 남지 않습니다.

불일치가 있으면 적용하지 않습니다

다음 상황에서는 아무 작업도 수행하지 않고 멈춥니다.

  • 이미 적용한 파일의 내용이 변경된 경우(sha256 불일치)
  • 적용 이력에는 있지만 파일이 없는 경우
  • 이미 적용한 번호보다 작은 번호의 새 파일이 생긴 경우

이미 배포한 마이그레이션 파일은 수정하지 말고, 새 번호의 파일로 변경 사항을 추가하세요.

ORM 마이그레이션 도구와 함께 사용하기

prisma migratedrizzle-kitSQL 생성에만 사용하세요. 생성된 SQL을 migrations/NNNN_*.sql로 옮긴 뒤 runlot pg migrate로 적용합니다.

# Prisma
npx prisma migrate diff --from-schema-datamodel prisma/schema.prisma \
  --to-schema-datasource prisma/schema.prisma --script > migrations/0003_posts.sql

# Drizzle
npx drizzle-kit generate
cp drizzle/0003_*.sql migrations/0003_posts.sql

워커 안에서는 prisma migrate deploy를 실행할 수 없습니다. 워커에 Prisma의 migration engine이 없기 때문입니다.

TypeORM의 synchronize와 Sequelize의 sync({ force: true })는 런타임에 DDL을 실행하므로 동작합니다. 개발 중에는 편리하지만 프로덕션 마이그레이션 방식으로 사용하지 마세요.

SQL을 한 번만 실행해야 할 때

runlot pg execute -c "alter table posts add column pinned boolean not null default false"
runlot pg execute -f ./fix.sql

이 명령으로 실행한 SQL은 적용 이력에 남지 않습니다. 스키마 변경은 마이그레이션 파일로 관리하는 방법을 권장합니다.

이 페이지의 목차