본문 바로가기

문돌이 존버/Django 스터디

장고(Django), 마이그레이션을 통한 데이터베이스 스키마 관리(1), (2)

반응형
본 글은 Holix의 "리액트와 함께 장고 시작하기 Complete" 강의를 듣고 작성한 일지입니다.

장고의 Migrations는 모델의 변경내역을 "데이터베이스 스키마"로 반영시키는 효율적인 방법을 제공합니다. 주의할 점은 이미 장고 이전에 데이터베이스를 따로 이용하고 있었다면 장고의 Migrations를 활용할 수 없습니다. 즉 데이터베이스 스키마 설계까지만 완성된 상태라면 장고를 통해 손쉽게 데이터베이스를 구성할 수 있습니다.

아래는 Migrations 관련 명령입니다.

# 마이그레이션 파일 생성
python manage.py makemigrations <앱 이름>

# 지정 데이터베이스에 마이그레이션 적용
python manage.py migrate <앱 이름>

# 마이그레이션 적용 현황 출력
python manage.py showmigrations <앱 이름>

# 지정 마이그레이션의 SQL 내역 출력
python manage.py sqlmigrate <앱 이름> <마이그레이션-이름>

Migration 파일

데이터베이스에 어떤 변화를 가하는 Operation들을 나열하는 것입니다. 예를 들어, 테이블 생성/삭제 및 필드 추가/삭제 등이 있습니다. 또한 데이터 마이그레이션 등 커스텀 파이썬/SQL Operation도 있습니다.

makemigrations 명령을 통해 대개 모델로부터 자동 생성이 됩니다. 주의할 점은 같은 Migration 파일이라 할지라도 DB 종류에 따라 다른 SQL이 생성된다는 것입니다. 모든 데이터베이스 엔진들이 같은 기능을 제공하지 않기 때문인데, 간단한 예로 이전 버전 sqlite DB에서는 기존 테이블에 컬럼 추가가 지원되지 않는다고 합니다.

지금까지의 로직은 아래와 같습니다. migrate 명령을 통해 DB에 적용하기 전 반드시 마이그레이션 파일 내역이 의도에 맞게 생성되었는지 확인해야 합니다.

그렇다면 언제 makemigrations를 할까요? 먼저, 모델 필드 관련된 어떠한 변경이라도 발생 시 마이그레이션 파일을 생성합니다. 실제로 DB 스키마에 가해지는 변화가 없더라도 수행해야 합니다. 이는 마이그레이션 파일이 모델의 변경내역을 누적하는 역할을 하기 때문입니다. 따라서 적용된 마이그레이션 파일은 절대 삭제하면 안되고 마이그레이션 파일이 너무 많아질 경우, squashmigrations 명령으로 다수의 마이그레이션 파일을 통합할 수 있습니다.

Migrate 정/역 방향

# 미적용 <마이그레이션 파일>부터 <최근 마이그레이션 파일>까지 정방향으로 순차적 진행
python manage.py migrate <앱이름>
# 지정된 <마이그레이션 이름>이 현재 적용된 마이그레이션보다
# 이후라면 정방향 순차적 foward 수행
# 이전이라면 지정 마이그레이션 이전까지 역방향으로 순차적 backward 수행
python manage.py migrate <앱이름> <마이그레이션 이름>

즉 지금 상태의 마이그레이션 보다 이전의 마이그레이션 버전을 입력하면 그때로 되돌아가는 것(rollback)입니다. 마이그레이션 이름 지정은 겹치지만 않는다면 식별할 수 있는 위치까지만 해도 됩니다. 예를 들어, 아래 경우가 있다고 생각합시다.

shop/migrations/0002_create_field.py
shop/migrations/0002_update_filed.py

이때 python manage.py migrate blog 0002까지만 하면 2개 파일에 매칭되므로 오류가 나고, 0002_c까지 해주면 위 파일만 해당될 것입니다. 그리고 최초의 상태로 돌아가고 싶다고 한다면 python manage.py migrate blog zero를 입력하시면 됩니다.

장고에서는 기본키로 id(AutoField) 필드를 디폴트로 생성하기 때문에 id 필드가 항상 존재할 것입니다. 모든 DB 테이블에는 각 row의 식별 기준인 기본키(Primary Key)가 필요합니다. 만약 다른 필드를 기본키로 지정하고 싶다면 primary_key=True 옵션을 적용하면 됩니다.

(참고) 마이그레이션 순서는 파일명으로 정렬하는 것이 아니라 마이그레이션 파일 내부에 있는 dependencies 에 따라 결정되는 것입니다.


이미 models.py에서 스키마를 생성하고 난 뒤, 새로운 필드를 추가해야 하는데 해당 필드가 필수필드일 경우를 살펴보겠습니다. 필수필드 여부는 blank 및 null 옵션이 모두 False일 때이며 이것이 디폴트입니다. 그리고 makemigrations 명령을 수행할 때 기존 Record에 어떤 값을 채워넣을 지 묻습니다.

option 1) 지금 그 값을 입력
option 2) 명령 수행 중단

(공동 관리 팁) 개발 시 "서버에 아직 반영하지 않은" 마이그레이션을 다수 생성한 경우 해결 방법은 2가지가 있습니다. 그래도 서버에 반영(migrate)하지 말고 하나의 마이그레이션으로 합쳐서 적용하는 것이 좋습니다.

option 1) 서버에 미적용한 마이그레이션들을 모두 롤백(rollback)하고 롤백된 마이그레이션을 모두 제거한 뒤 새롭게 마이그레이션 파일 생성
option 2) 미적용 마이그레이션들을 하나로 합치기(squashmigrations 명령)

참고로 강의에선 1번 방법을 더 추천한다고 합니다!

728x90
반응형