본문 바로가기
Web/BackEnd

[Backend] flyway 사용하기

by 희조당 2023. 10. 11.

🙋 들어가며

우리는 코드를 관리하기 위해서 git이라는 형상 관리 툴을 사용합니다.

반면에 여러분들은 DB는 어떤 것으로 형상을 관리하시나요?

바로 Flyway가 DB에 대한 형상 관리를 제공합니다. 이번 글에서 간단하게 사용법을 알아보겠습니다. 😋


🪽 flyway란?

공식 문서에는 다음과 같이 소개합니다. 😮

Flyway is an open-source database migration tool.

DB 형상 관리를 도와주는 도구입니다. 심지어 오픈 소스입니다! 😋

🤔 왜 사용할까?

저는 개발을 할 때 DDL을 직접 작성해서 관리하는 것을 선호합니다.

스키마에 변경사항이 생기면 하나하나 수정했습니다. (다행히도 꼼꼼한 성격 때문에 아직까진 실수한 적 없습니다 😜)

 

만약 관리해야 할 DB가 많다면 이 과정은 정말 지루한 반복적인 작업입니다.

또한, JPA를 사용할 때 실수로라도 ddl-auto 옵션을 건든다면 끔찍한 일이 벌어질 것 같습니다.

즉, 이런 잠재적인 휴먼 에러를 방지할 수 있습니다.

 

변경사항들은 따로 문서화해놓지 않는다면 추적이 어렵습니다.

그런데 Flyway는 이런 변경사항을 추적할 수 있게 해줍니다 😲


👻 사용법

Flyway를 사용하기 위해서는 따라야 할 컨벤션이 존재합니다.

📜 스크립트 위치

작성한 sql 파일의 위치는 /resources/db/migration입니다.

이는 기본값이며 .yml 파일에 spring.flyway.locations 값을 다른 경로로 변경해 줄 수 있습니다.

🧾 스크립트 네이밍

작성할 스크립트(sql 파일)의 네이밍은 다음과 같이 컨벤션이 존재합니다.

출처 : flyway 공식 문서

1️⃣ Prefix

어떤 스크립트인지 나타내며, 3가지 prefix가 존재합니다.

  • V(versioned) : 버전에 따라 Update
  • U(undo) : 이전 버전으로 Rollback
  • R(repeatable) : 버전 상관 없이 매번 실행 (한번만)

2️⃣ Version

스크립트의 버전을 나타냅니다.

V와 U Prefix에서는 버전을 이용하기 때문에 명시하고, R Prefix에서는 항상 실행되므로 명시하지 않습니다.

새로운 스크립트는 항상 이전보다 높아야 합니다. 이전 버전보다 낮다면 적용되지 않습니다.

단순한 숫자도 가능하지만, 231011 같은 날짜 혹은 따로 지정한 값도 이전보다 높은 값이라면 모두 가능합니다. 

3️⃣ Separator

무조건 언더바(_) 2개입니다. 이유는 약속입니다 🤙🤙

4️⃣ Description

어떤 스크립트인지 나타내는 부분입니다. 

단어를 구분하기 위해서 언더바(_) 1개를 사용하고 이외에는 자유롭게 작성하면 됩니다.

⚙️ 설정하기

gradle 기반의 프로젝트에서 적용하기 위해서는 다음과 같은 의존성이 필요합니다.

implementation 'org.flywaydb:flyway-core'

만약 Mysql 8.x 버전이거나 MariaDB를 사용하면 다음 의존성을 추가로 작성해 줍니다.

implementation 'org.flywaydb:flyway-mysql'

 

이후 .yml 파일(.properties)에 flyway 관련 옵션을 추가해 줍니다.

spring.flyway.enabled은 기본값이 true으로 작성하지 않으셔도 무방합니다 😜

spring:
  datasource:
    # datasource는 각자에 맞게 작성한다.
      
  jpa:
    # jpa 속성은 각자에 맞게 작성한다.
    hibernate:
      ddl-auto: validate

  flyway:
    enabled: true
    baseline-on-migrate: true

📩 baseline-on-migrate

변경 이력 테이블(flyway_schema_history)을 생성을 도와주는 옵션입니다.

기본적으로 변경 이력 테이블이 생성되지만 조건에 따라 다르게 옵션을 다르게 부여해야 합니다.

  1. 기존 테이블 O, 변경 이력 테이블 X : true 
  2. 기존 테이블 X, 변경 이력 테이블 O : false

😈 ddl-auto: validate

none으로 설정해도 무방하지만 DB 테이블과 엔티티에 대한 검증을 위해서 적용시켰습니다.

둘의 구조가 일치하지 않는다면 application은 실행되지 않습니다.

따라서, 실수로 엔티티의 구조를 변경한 뒤 테이블에 반영하지 않는 상황을 방지해 줍니다.


👀 사용해보기

V1__init_schema.sql이라는 파일을 작성해서 다음과 같은 스크립트를 만들었습니다.

CREATE TABLE IF NOT EXISTS users(
    id           BIGINT PRIMARY KEY AUTO_INCREMENT,
    name         VARCHAR(10)  NOT NULL,
    email        VARCHAR(50)  NOT NULL,
);

 

이후 애플리케이션을 실행시켜주면 다음과 같은 로그가 발생합니다.

 

이후 flyway_schema_history 테이블이 생성되었고 조회해보면 다음과 같이 이력이 남게 됩니다.

✅ 속성 추가하기

요구사항이 변경되어 유저 테이블에 나이 속성이 추가된다면 다음과 같이 작성하면 됩니다.

// V2__add_age.sql
ALTER TABLE users ADD COLUMN age INT;

 

이후 다시 시작하면 다음과 같은 로그가 발생하게 되고

 

변경 이력 테이블에 잘 반영된게 확인됩니다. 👍


😜 정리

  • flyway는 DB 형상 관리 툴이다.
  • flyway로 휴면 에러를 방지할 수 있고 변경사항을 추적할 수 있다.
  • 지켜야 할 컨벤션이 존재한다.
  • 변경에 대한 스크립트를 깜빡하는 것을 방지하는 것은 ddl-auto: validate로 방지한다

-Reference:

https://flywaydb.org/documentation/

 

😋 지극히 개인적인 블로그지만 댓글과 조언은 제 성장에 도움이 됩니다 😋

댓글