슬기로운 개발자생활/Rust

&Axum SQLx를 활용한 데이터베이스 중급 - 마이그레이션 (Migration)

개발자 소신 2024. 9. 24. 11:42
반응형

데이터베이스 마이그레이션은 애플리케이션 개발에서 필수적인 부분입니다. 스키마 변경, 새로운 테이블 추가, 기존 테이블 수정 등의 작업을 체계적으로 관리해야 합니다. 이 글에서는 마이그레이션의 필요성과 개념을 이해하고, sqlx-cli를 사용하여 데이터베이스 마이그레이션을 관리하는 방법을 알아보겠습니다. 또한, 실제로 데이터베이스 스키마 버전 관리를 실습해 보겠습니다.


3-1. 마이그레이션의 필요성과 개념 이해

1. 마이그레이션이란?

마이그레이션(Migration)은 데이터베이스의 스키마 변경 사항을 관리하고 적용하는 과정을 말합니다. 마이그레이션을 통해 다음을 수행할 수 있습니다.

  • 새로운 테이블 생성
  • 기존 테이블 수정 (컬럼 추가, 삭제, 변경)
  • 인덱스, 제약 조건 추가 또는 제거
  • 데이터 변환 또는 초기 데이터 삽입

2. 마이그레이션의 필요성

  • 버전 관리: 데이터베이스 스키마의 변경 이력을 추적하고 관리할 수 있습니다.
  • 협업 지원: 여러 개발자가 동시에 작업할 때 스키마 변경 사항을 공유하고 충돌을 방지합니다.
  • 배포 자동화: 개발, 테스트, 프로덕션 환경에서 일관된 스키마를 유지할 수 있습니다.
  • 복구 용이성: 문제 발생 시 이전 버전으로 롤백할 수 있습니다.

3. 수동 스크립트 실행의 한계

데이터베이스 변경 사항을 수동으로 SQL 스크립트를 실행하여 관리하는 것은 다음과 같은 문제가 있습니다.

  • 변경 이력 관리의 어려움
  • 스크립트 실행 순서의 혼동 가능성
  • 환경별로 스크립트 누락 또는 중복 실행 위험
  • 협업 시 스키마 동기화의 어려움

3-2. sqlx-cli를 이용한 마이그레이션 관리

1. sqlx-cli 소개

sqlx-cli는 SQLx에서 제공하는 커맨드라인 도구로, 데이터베이스 마이그레이션을 관리하고 쿼리 검증을 수행할 수 있습니다. 주요 기능은 다음과 같습니다.

  • 마이그레이션 파일 생성, 적용, 롤백
  • 컴파일 시점에 쿼리 검증을 위한 데이터베이스 연결

2. sqlx-cli 설치

cargo를 사용하여 sqlx-cli를 설치합니다.

cargo install sqlx-cli --no-default-features --features postgres

주의: --no-default-features 옵션을 사용하여 필요한 데이터베이스 드라이버만 포함합니다. 여기서는 PostgreSQL을 사용하므로 --features postgres를 지정합니다.

3. 마이그레이션 디렉토리 구조

프로젝트 루트 디렉토리에 migrations 디렉토리를 생성합니다.

mkdir migrations

migrations 디렉토리에는 마이그레이션 파일들이 위치하게 됩니다.

4. 마이그레이션 파일 생성

sqlx migrate add 명령어를 사용하여 새로운 마이그레이션 파일을 생성합니다.

sqlx migrate add create_books_table

이 명령을 실행하면 migrations 디렉토리에 타임스탬프가 포함된 마이그레이션 파일이 생성됩니다.

예시:

migrations/
├── 20231001000000_create_books_table.up.sql
├── 20231001000000_create_books_table.down.sql
  • .up.sql: 마이그레이션을 적용할 때 실행되는 SQL 스크립트
  • .down.sql: 마이그레이션을 롤백할 때 실행되는 SQL 스크립트

5. 마이그레이션 파일 작성

업그레이드 스크립트 (.up.sql)

-- migrations/20231001000000_create_books_table.up.sql

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    published_date DATE
);

다운그레이드 스크립트 (.down.sql)

-- migrations/20231001000000_create_books_table.down.sql

DROP TABLE IF EXISTS books;

6. 마이그레이션 적용

데이터베이스 URL을 환경 변수로 설정합니다. .env 파일에 이미 설정되어 있다면 다음 명령어로 마이그레이션을 적용할 수 있습니다.

sqlx migrate run

출력 예시:

Executing migration 20231001000000_create_books_table

마이그레이션이 성공적으로 적용되면 books 테이블이 생성됩니다.

7. 마이그레이션 상태 확인

현재 마이그레이션 상태를 확인하려면 다음 명령어를 사용합니다.

sqlx migrate info

출력 예시:

Migration                                 Applied At                  Duration
-------------------------------------------------------------------------------
20231001000000_create_books_table         2023-10-01 12:00:00         50.123ms

3-3. 데이터베이스 스키마 버전 관리 실습

1. 새로운 마이그레이션 생성

books 테이블에 새로운 컬럼을 추가해 보겠습니다. 예를 들어, description 컬럼을 추가한다고 가정합니다.

sqlx migrate add add_description_to_books

생성된 마이그레이션 파일:

migrations/
├── 20231001000000_create_books_table.up.sql
├── 20231001000000_create_books_table.down.sql
├── 20231002000000_add_description_to_books.up.sql
├── 20231002000000_add_description_to_books.down.sql

2. 마이그레이션 파일 작성

업그레이드 스크립트 (.up.sql)

-- migrations/20231002000000_add_description_to_books.up.sql

ALTER TABLE books
ADD COLUMN description TEXT;

다운그레이드 스크립트 (.down.sql)

-- migrations/20231002000000_add_description_to_books.down.sql

ALTER TABLE books
DROP COLUMN IF EXISTS description;

3. 마이그레이션 적용

sqlx migrate run

출력 예시:

Executing migration 20231002000000_add_description_to_books

이제 books 테이블에 description 컬럼이 추가되었습니다.

4. 롤백 실행

마이그레이션을 롤백하여 이전 상태로 되돌릴 수 있습니다.

sqlx migrate revert

출력 예시:

Reverting migration 20231002000000_add_description_to_books

다시 한 번 sqlx migrate revert를 실행하면 최초 마이그레이션도 롤백됩니다.

5. 특정 버전으로 마이그레이션

sqlx migrate run은 모든 마이그레이션을 순서대로 적용합니다. 특정 버전까지 마이그레이션을 적용하거나 롤백하려면 마이그레이션 파일을 조정하거나 수동으로 관리해야 합니다.

6. 마이그레이션과 코드의 동기화

마이그레이션을 적용한 후, 코드에서도 스키마 변경 사항을 반영해야 합니다. 예를 들어, Book 구조체에 description 필드를 추가합니다.

#[derive(Debug, Serialize, Deserialize)]
struct Book {
    id: i32,
    title: String,
    author: String,
    published_date: Option<NaiveDate>,
    description: Option<String>,
}

참고: chrono 크레이트를 사용하여 날짜 타입을 처리할 수 있습니다.

 

Cargo.tomlchrono 의존성 추가:

[dependencies]
chrono = { version = "0.4", features = ["serde"] }

7. 데이터베이스 변경 사항 적용 후 테스트

애플리케이션을 다시 빌드하고 실행하여 변경 사항이 정상적으로 적용되었는지 확인합니다.

cargo run

추가 실습: 마이그레이션 충돌 관리

1. 마이그레이션 충돌 상황

여러 개발자가 동시에 마이그레이션을 생성하고 적용하면 충돌이 발생할 수 있습니다. 이를 방지하기 위해 마이그레이션 파일을 생성할 때 항상 최신 상태를 유지하고, 타임스탬프를 기반으로 마이그레이션을 관리합니다.

2. 마이그레이션 파일의 버전 관리

Git 등의 버전 관리 시스템을 사용하여 마이그레이션 파일을 관리합니다. 마이그레이션 파일을 커밋하고 푸시하여 팀원들과 공유합니다.

3. 팀 협업 시 주의사항

  • 마이그레이션을 생성하기 전에 항상 최신 코드를 풀(Pull) 받습니다.
  • 마이그레이션 파일의 순서를 유지하기 위해 타임스탬프를 기반으로 파일명을 지정합니다.
  • 충돌이 발생한 경우 마이그레이션 파일을 병합하고 순서를 조정합니다.

결론

이번 글에서는 데이터베이스 마이그레이션의 필요성과 개념을 이해하고, sqlx-cli를 사용하여 마이그레이션을 관리하는 방법을 배웠습니다. 마이그레이션을 통해 데이터베이스 스키마 변경 사항을 체계적으로 관리하고, 팀 협업 시 스키마 동기화를 원활하게 할 수 있습니다.

마이그레이션은 애플리케이션 개발에서 매우 중요한 부분이며, 이를 효율적으로 관리하면 개발 생산성을 높일 수 있습니다. 앞으로의 개발에서는 마이그레이션을 적극적으로 활용하여 데이터베이스 스키마를 관리해 보세요.


참고 자료


주의: 이 글은 학습 목적으로 작성되었으며, 실제 애플리케이션 개발 시 보안, 성능, 에러 처리 등에 대한 추가 고려가 필요합니다.

반응형