-
Spring Boot Flyway 적용하기(flyway, h2 DB test 에러 해결)프로젝트/선착순 쿠폰 발급 시스템 2023. 4. 30. 00:01728x90
개요
DB 형상관리를 위해 Flyway를 도입하고자 합니다.
Flyway란?
git을 통하여 우리가 코드를 관리하는 것의 DB 버전입니다.
데이터베이스의 DDL의 이력을 쌓아 DDL이 어떻게 변화되었는지 관리하는 툴으로 사용할 수 있습니다.
실무에서는 local prod등 실제 서버와 개발환경이 나뉘어 있습니다.
이때 local 에서 변경한 DB의 스키마나 데이터를 운영 DB에 반영할 때 누락하는 것을 막기 위해 사용합니다.
Flyway Convention
- 기본 위치는 main/reousrces/db/migration (커스텀 설정 가능)
- Prefix
- V(Versioned)
- 현재 버전을 새로운 버전으로 업그레이드
- U(Undo)
- 현재 버전을 이전 버전으로 되돌리는 경우
- R(Repetable)
- 버전에 관계 없이 매번 실행하는 경우
- V(Versioned)
- Verison
- V와 U는 버전을 명시해야 한다.
- R은 버전을 명시할 필요가 없다.
- 새로 스크립트를 작성한다면 스크립트의 버전을 이전보다 꼭 높게 적어야 한다.
- 이전에 1.0이였다면 이후에는 2.0을 사용해야 한다.
- 낮은 숫자를 쓰면 Flyway가 이를 무시한다
- separator
- 무조건 __(언더바 2개)로 작성해야 한다.
- Description
- 단어 구분은 _(언더바 1개)로 작성해야 한다.
build.gradle 의존성 추가
dependencies { //flyway 의존성 추가 implementation ("org.flywaydb:flyway-core:6.4.2") }
application-infra.yml 설정 추가
spring: flyway: enabled: true baseline-on-migrate: true
enable은 기본값이 true이지만 명시적으로 적어줍니다.
baseline-on-migrate
- 기본값 false
- false로 하려면 히스토리 테이블(flyway_schema_history)이 생성되어 있어야 함
- true로 하면 히스토리 테이블이 없을 경우 생성함
SQL 파일 작성
디렉터리 계층구조
resources db
migration
V1__init.sql
resources/db/migration/V1__init.sql을 생성합니다.
create table member ( id bigint generated by default as identity, member_id varchar(255), password varchar(255), nick_name varchar(255), full_name varchar(255), primary key (id) );
이는 JPA Entity와 맞춰줍니다.
package com.demo.infrastructure.member.signup.entity import com.demo.domain.member.entity.Member import javax.persistence.Column import javax.persistence.Entity import javax.persistence.Table import javax.persistence.Id import javax.persistence.GeneratedValue import javax.persistence.GenerationType.IDENTITY @Entity @Table(name = "member") class MemberJpaEntity( @Column private val memberId: String, @Column private val password: String, @Column private val nickName: String, @Column private val fullName: String, ) { @Id @GeneratedValue(strategy = IDENTITY) private val id: Long = 0L }
실행해 보기
curl --location --request POST 'localhost:8080/member' \ --header 'Content-Type: application/json' \ --data-raw '{ "memberId": "any", "password": "any", "nickName": "any", "fullName": "any" }'
ddl-auto: none 임에도 불구하고 flyway로 인해 테이블이 만들어지게 됩니다.
200 OK가 떨어집니다.
테스트 코드
Flyway를 활용하여 테스트 코드까지 돌려보려고 합니다.
테스트 환경에서도 ddl-auto: none으로 설정합니다.
또한 flyway설정도 추가해 줍니다.
다음과 같은 에러가 떨어집니다.
Unable to determine H2 compatibility mode ----------------------------------------- SQL State : 42001 Error Code : 42001 Message : Syntax error in SQL statement "SELECT [*]VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'MODE'"; expected "TOP, DISTINCT, ALL, *, INTERSECTS (, NOT, EXISTS, UNIQUE, INTERSECTS"; SQL statement: SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'MODE' [42001-214]
다음과 같이 해결해보려고 했습니다.
spring: flyway: enabled: true baseline-on-migrate: true locations: classpath:/db/migration schemas: PUBLIC url: jdbc:h2:mem:reader
이렇게 해결했습니다.
//AS-IS implementation ("org.flywaydb:flyway-core:6.4.2") //To-be implementation ("org.flywaydb:flyway-core")
다음글을 참고하였는데 버전 충돌이 원인 같습니다.
https://stackoverflow.com/questions/71202470/h2-version-change-issue-from-1-4-200-to-2-0-202
다른 에러 발견
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "MEMBER" not found (this database is empty); SQL statement: insert into member (id, full_name, member_id, nick_name, password) values (default, ?, ?, ?, ?) [42104-214]
Member table이 생성되지 않은 것 같습니다.
모든 설정을 제거하니 잘 실행됩니다.
spring: flyway: enabled: true baseline-on-migrate: true
localtion을 잘 잡지 못한 것 같습니다.
참고자료
https://www.youtube.com/watch?v=pxDlj5jA9z4&t=191s
https://tecoble.techcourse.co.kr/post/2021-10-23-flyway/
'프로젝트 > 선착순 쿠폰 발급 시스템' 카테고리의 다른 글
Embedded Redis 구성하여 테스트 수행하기 (0) 2023.05.04 Event Driven Architecture란? (0) 2023.05.01 Database local dev환경 구성하기(postgreSQL with Docker) (0) 2023.04.29 회원 도메인 모듈 만들기 (0) 2023.04.27 gradle build 속도 개선하기 (0) 2023.04.25