ADR-0006: Migration: Atlas¶
Umbra 의 DB 스키마 마이그레이션은 Atlas 로 관리한다. 선언형 스키마를 source of truth 로 두고 마이그레이션을 자동 생성한다.
Status¶
Accepted
- Decided at — 2026-04-13
- Decided by — Pablo
Context¶
PostgreSQL 스키마의 버전 관리와 배포가 필요하다. 선택 기준:
- 선언형 스키마 지원 (desired state 정의 → 자동 diff)
- Schema drift detection (CI 에서 실제 DB 와 선언 스키마 비교)
- Neon branching 과 통합 가능
- 도메인별 schema (ADR-0020) 관리 용이
후보: Atlas, golang-migrate, goose, Flyway, Liquibase.
Decision¶
Atlas 를 마이그레이션 도구로 채택한다.
- Source of truth —
db/schema/*.sql(선언형 DDL) - 자동 생성 —
atlas migrate diff→db/migrations/ - 적용 —
atlas migrate apply --env {local,dev,prod}
선택 근거:
- 선언형 스키마 — 테이블 상태를 직접 기술하고 Atlas 가 diff 계산. 마이그레이션을 수동으로 쓰는 부담 없음
- Schema drift detection — CI 에서 선언 스키마와 실제 DB 가 불일치하면 실패. 수동 변경 방지
- Multi-schema 지원 — 도메인별 PostgreSQL schema 분리(ADR-0020)를 네이티브 지원
- Neon 과 통합 — PR 브랜치 DB 에 자동 적용, drift 결과를 PR 코멘트로 게시
Consequences¶
Positive¶
- Schema 변경의 의도가
db/schema/*.sql에 명확히 드러남 - 마이그레이션 파일은 자동 생성되어 사람이 편집하지 않음 (오류 감소)
- PR 마다 마이그레이션 적용 검증
- Schema drift 방지
Negative¶
- Atlas CLI 설치 필요 (mise 로 관리)
- 복잡한 데이터 이동(예: backfill)은 별도 스크립트 필요 (Atlas 는 schema 변경만)
- 학습 곡선 존재 (HCL 설정, env 개념)
Neutral¶
- 선언 스키마에 이미 변경을 반영했는데 마이그레이션 미생성 시 CI 에서 drift 로 실패
- destructive 변경(DROP COLUMN 등)은 수동 승인 게이트 필요
Alternatives considered¶
Alternative 1: golang-migrate¶
Pros
- Go 표준 마이그레이션 도구
- 레퍼런스 풍부
Cons
- Imperative (마이그레이션 파일을 수동 작성)
- Schema drift detection 없음
- 마이그레이션 간 의존성 관리 약함
Why rejected — 선언형 + drift detection 이 결정적. 수동 마이그레이션은 오류 빈번.
Alternative 2: goose¶
Pros
- 가볍고 단순
- 커뮤니티 활발
Cons
- Imperative 만 지원
- golang-migrate 와 유사 한계
Why rejected — 위와 동일.
Alternative 3: Flyway / Liquibase¶
Pros
- 엔터프라이즈급 성숙도
- 복잡한 시나리오 지원
Cons
- JVM 기반 (Go 프로젝트와 이질적)
- CLI 실행이 무거움
- Neon branching 통합 레퍼런스 부족
Why rejected — Go 생태계와 이질성이 DX 를 해침.
Alternative 4: GORM AutoMigrate¶
Pros
- 코드 기반 자동 마이그레이션
Cons
- GORM 을 쓰지 않음 (ADR-0005)
- 프로덕션 운영에 부적합한 패턴 (destructive 변경 추적 불가)
Why rejected — GORM 자체를 거부했고 AutoMigrate 는 프로덕션 부적합.
Compliance¶
db/schema/*.sql이 항상 latest desired state- 스키마 변경은 PR 에 반드시 포함 (schema 변경 + atlas migrate diff 결과)
- CI 는
atlas migrate lint로 위험한 변경 감지 - Destructive migration 은 수동 승인 (GitHub Actions approval)
Revisit triggers¶
- Atlas 가 특정 PostgreSQL 기능을 지원하지 못하게 되면 재평가
- 복잡한 데이터 이관이 반복되면 전용 migration runner 추가 검토