-
Notifications
You must be signed in to change notification settings - Fork 7
Flyway를 사용하는 이유
- 자세히보기 : https://jaehhh.tistory.com/119
- Flyway는 DB의 형상관리를 목적으로 하는 툴이다.
현재 우리는 배포 후 데이터를 관리해본 경험이 없다.
유지 보수 중 스키마 구조가 바뀌는 상황에 어떻게 대처할 것인가?
- 기존 테이블 (
SampleEntity
)
@Entity
public class SampleEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
- age 필드 추가
@Entity
public class SampleEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
}
이 상황에서 변화를 어떻게 처리할 것인가?
ALTER TABLE sample_entity ADD COLUMN age integer default 0
- 실수하기 좋다
- 작업하기 번거롭다
- 만약 데이터가 미리 있고, Entity쪽만 변경(age추가), DB 스키마를 수정하지 않았다면?
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'age' in 'field list'
에러가 발생한다.
궁극적인 목표
- DB에 접속해서 TABLE을 직접 건들지 않으며, age 컬럼 포함한 신규데이터를 저장한다.
- 이전 나이가 포함되지 않는 데이터는 나이 필드를 0으로 초기화한다.
- git으로 관리한다 → 파일로 관리할 수 있어야 한다.
dependencies {
implementation('org.flywaydb:flyway-core:6.4.2')
}
-
data source 설정 (DB정보)
spring: datasource: driver-class-name: org.h2.Driver url: jdbc:h2:tcp://localhost/~/flyway username: sa password:
-
flyway 설정
spring: jpa: properties: hibernate: jdbc.lob.non_contextual_creation: true generate-ddl: false flyway: enabled: true
-
Spring boot 2 이상의 경우 아래 설정 추가
spring: flyway: baseline-on-migrate: true
등록하려는 시점
의 DB 스키마 구조를 입력해야 한다.
이 파일을 기준으로 flyway가 DB버전 관리
를 하게된다.
- 버전 관리가 어렵다면 일단
V {숫자}__{설명}. sql
으로 생각하자.
**V1__init.sql
:**등록시점의 DB 스키마 구조 입력
drop table if exists sample_entity;
create table sample_entity(
id bigint auto_increment,
name varchar(255),
primary key (id)
);
public class SampleEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age; // 추가한 부분
}
ALTER TABLE sample_entity ADD COLUMN age integer default 0
- V(Versioned): 현재버전을 새로운 버전으로 업데이트
- U(Undo): 현재 버전을 이전버전으로 되돌리는 경우
- R(Repeatable): 버전에 관계 없이 매번 실행하는 경우
스크립트의 버전을 이전보다 꼭 높게 적어야 한다.
- V와 U는 버전을 명시한다.
- R은 버전을 명시하지 않는다. (매번 실행되기 때문이다)
무조건 __(언더바 2개)
로 작성
스크립트 내용에 맞게 자유롭게 적는다.
단어 구분은 _(언더바 1개)
로 한다.
https://www.youtube.com/watch?v=pxDlj5jA9z4
https://tecoble.techcourse.co.kr/post/2021-10-23-flyway/
[https://ecsimsw.tistory.com/entry/Flyway로-DB-Migration](https://ecsimsw.tistory.com/entry/Flyway%EB%A1%9C-DB-Migration)
[https://www.blog.ecsimsw.com/entry/Flyway-DB-마이그레이션-기존-데이터가-있는-경우](https://www.blog.ecsimsw.com/entry/Flyway-DB-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%EA%B8%B0%EC%A1%B4-%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B0%80-%EC%9E%88%EB%8A%94-%EA%B2%BD%EC%9A%B0)
-
h2
에서jdbc:h2:mem:testdb;MODE=MYSQL
을 적용 -
V1__init.sql
의engine=InnoDB default charset utf8mb4;
부분에서 에러가 발생함
- h2 문법으로 적용하면 성공이 됨 → 스키마를 h2, MySQL 둘다 관리해야 하기 때문에 적용X
- 로컬 test DB를 MySQL로 변경
-
h2
에서MySQL
로 마이그레이션 적용 - 테스트 격리가 안되는 현상 발생 (기존 테스트 실패)
- 프로덕션 코드는 build가 통과한다. → 엔티티와 DB스키마가 일치한다 → 테스트에 Flyway 스키마를 적용할 필요가 없다
-
Flyway + MySQL
: 배포서버, 로컬서버 프로덕션 코드 - h2 : 배포서버, 로컬서버 테스트 코드
-
-
flyway.enabled=false
를 꼭 설정하자
기존 테이블 내용
과 새롭게 추가된 스키마 사이 추가되는 과정에서 중복된 내용이 있거
나 관리되는 스키마 내용이 다를 때 에러
가 발생한다.
-
drop table flyway_schema_history
를 적용, ddl auto를validate
한 뒤 실행해보자.
flyway 실행예시
-
flyway_schema_history
테이블이 없거나 비어있다면 V1부터 차례로 모두 실행한다. -
flyway_schema_history
테이블에 V1, V2가 있다면 다음실행시 V3부터 실행된다.
실행 중 기존 테이블과 스키마가 중복되는 부분이 있다면 에러가 발생할 수 있다.
→ 스키마를 변경하거나, 로컬DB인 경우 다른 테이블
, flyway_schema_history
를 삭제 후 다시 실행해보자