Flyway와 PostgreSQL 스키마 변경
entity가 schema를 자동으로 바꾸게 두면 개발자의 로컬 DB는 편하지만, 언제 어떤 SQL이 적용됐는지 남지 않습니다. 이 프로젝트에서 Hibernate는 매핑을 검증하고, Flyway만 schema를 변경합니다. PostgreSQL 컨테이너를 사용해 운영과 같은 SQL 의미로 확인합니다.
스키마 이력은 애플리케이션과 함께 버전 관리한다
Flyway는 파일명의 버전 순서로 SQL을 실행하고 schema history에 버전과 checksum을 남깁니다. 그 이력은 “현재 schema가 어떻게 여기까지 왔는가”에 대한 배포 기록입니다. 이미 공유된 migration을 수정하지 않는 이유도 여기에 있습니다.
첫 migration과 PostgreSQL 실행 환경을 작성한다
V1은 ch3-1의 entity와 한 컬럼도 엇갈리지 않아야 합니다. enum은 문자열로, UUID는 PostgreSQL UUID로, @Version은 BIGINT로 대응시킵니다. Compose volume은 컨테이너를 재시작해도 이력이 남는지 확인하기 위해 보존합니다.
CREATE TABLE study_session (
id UUID PRIMARY KEY,
subject VARCHAR(80) NOT NULL,
topic VARCHAR(120) NOT NULL,
study_date DATE NOT NULL,
minutes INTEGER NOT NULL CHECK (minutes BETWEEN 1 AND 1440),
status VARCHAR(20) NOT NULL,
version BIGINT NOT NULL DEFAULT 0
);services:
postgres:
image: postgres:18-alpine
environment:
POSTGRES_DB: studylog
POSTGRES_USER: studylog
POSTGRES_PASSWORD: studylog
ports:
- "5432:5432"
volumes:
- studylog-data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U studylog -d studylog"]
interval: 5s
timeout: 3s
retries: 10
volumes:
studylog-data:study-log:
zone: Asia/Seoul
daily-limit-minutes: 480
spring:
datasource:
url: jdbc:postgresql://localhost:5432/studylog
username: studylog
password: studylog
jpa:
hibernate:
ddl-auto: validate
flyway:
validate-migration-naming: trueclean DB와 기존 DB에서 validate를 확인한다
첫 실행은 빈 volume에 V1을 적용하고, 두 번째 실행은 이미 적용된 checksum을 확인한 뒤 넘어가야 합니다. 아래 startup 로그를 확인하고 Ctrl+C로 종료한 뒤, 같은 spring-boot:run 명령을 한 번 더 실행해 이력이 중복 적용되지 않는지 확인합니다.
docker compose up -d --wait postgres
./mvnw -q spring-boot:runFlyway schema history에 V1이 한 번 기록되고 Hibernate validate가 성공해야 합니다.실패한 migration은 파일 수정이 아니라 새 migration으로 복구한다
로컬에서 V1을 고치고 volume을 지우면 문제가 사라진 듯 보이지만, 이미 V1을 적용한 환경은 checksum 불일치로 멈춥니다. 파괴적 변경은 데이터 이관과 롤백 계획을 포함한 새 migration으로 작성하고, 배포 전에 기존 데이터가 있는 복사 DB에서 연습합니다.
저장 경계가 실제 DB에 안착했습니다. 다음 장에서는 이 데이터를 누가 읽고 바꿀 수 있는지를 HTTP 진입점보다 앞에서 결정합니다.