2.4 마이그레이션
- 장고에서 모델링하면 SQL(DDL)로 해당 모델 기반의 플랜을 작성해줌
- DDL (데이터 정의어)
- SQL 중에서 데이터베이스를 정의하는 문법
- CREATE, ALTER, DROP, TRUNCATE 등
- DDL (데이터 정의어)
- 장고에서는 이 작업을 마이그레이션 또는 DB 마이그레이션이라고 부름
- 장고에서는 DB 마이그레이션을 하기 위한 다음과 같은 명령어를 제공
- 마이그레이션
- 컴퓨터 분야에서는 보통 시스템의 변화 또는 시스템의 이동을 의미
- 데이터베이스의 구조 변화를 의미
- 데이터베이스가 가지고 있는 데이터에 일괄적인 변화를 주는 작업
- ex. 2년 이상 로그인하지 않은 회원을 휴면 계정으로 처리하는 데이터 마이그레이션
- 종류
- 마이그레이션
2.4.1 makemigrations
<장고에게 DDL을 자문 받는 명령어>
- 장고 프로젝트의 migrations 폴더의 하위 파일들과 models.py와의 차이를 비교하는 명령어
- 이전에 수행된 migrations 폴더의 하위 파일을 전부 읽어서 현재 models.py에 존재하는 모델과 비교해서 차이가 있는지 검사하고 만약 차이가 있다면 이를 일치시키기 위해 새로운 마이그레이션 파일을 생성
- 이 안에는 models.py와 migrations 정보를 일치시키기 위한 DDL이 포함되어 있음
- 여기서 주의해야할 점은 이 DDL은 장고가 제안해주는 정보일 뿐이지 완벽하지 않을 수 있음
- makemigrations는 마치 개발자가 장고라는 이름을 가진 DBA에게 DDL 수행 계획을 자문하는 것과 같은 역할
- makemigrations를 수행했을 때 생성되는 00xx_auto_xxxxx.py 파일이 장고라는 DBA에게 자문으로 얻은 DDL 수행 계획인 것
*makemigrations를 수행할 때마다 각 장고 앱에서 모델 변경 사항이 발견되면 1개의 마이그레이션 파일이 생성됨
- 하지만, 장고는 무수한 if-else 문으로 도배된 DBA일 뿐임
- 장고가 제안한 DDL은 개발자가 살펴보고 적절한지 판단해야 함
- 장고가 제안한 DDL은 데이터베이스에 즉시 반영되지 않게 설계되어 있음
2.4.2 Operations
<장고 마이그레이션 모듈이 가지고 있는 명령어>
- 장고가 가지고 있는 Operation의 종류로는 여러 가지가 있음
- 모든 것을 일일이 분석하는 것은 불필요
- dependencies란 마이그레이션 파일이 수행되려면 반드시 dependencies에 언급된 마이그레이션 파일이 먼저 수행되어야 한다는 제약을 의미함
- dependencies= [ ('study_example_app', '0001_initial'), ]
- operation 사용 예시
- CreateModel
- 장고 모델에 명시된 옵션 값을 토대로 테이블을 생성하는 DDL을 만들어줌
-- 위 옵션 값을 가진 CreateModel Operation은 아래와 같은 DDL을 만들어준다. Create TABLE "b_model" ( "id" serial NOT NULL PRIMARY KEY, "b_field" varchar(16) NOT NULL, "b_int_field" integer NOT NULL );
- migrations.CreateModel( name='Bmodel', fields=[ ('id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('b_field', models.CharField(max_length=16)), ('b_int_field', models.IntegerField(default=3)), ], options={ 'db_table' : 'b_model', }, ),
- AddField
- AddField로 생성된 DDL
-- 위 옵션 값을 가진 AddField Operation은 아래와 같은 DDL을 만들어준다. ALTER TABLE "b_model" ADD COLUMN "a_111_field" varchar(32) DEFAULT 'aa' NOT NULL; ALTER TABLE "b_model" ALTER COLUMN "a_111_field" DROP DEFAULT;
- CreateModel이 깔끔하게 1개의 DDL을 만들어준 것과 달리
- AddField는 DDL이 하나 더 생성되어있음
- migrations.AddField( model_name='amodel', name='a_111_field', field=models.fields.CharField( default='aa', max_length=32 ), ),
- 장고 필드에 default=’aa’라는 옵션을 부여했지만 왜 2번째 DDL을 추가해서 굳이 DROP DEFAULT를 하는 것인가?DROP DEFAULT: 칼럼에 부여된 default=’aa’ 옵션을 제거하는 DDL
- → 장고 ORM의 특징으로 연결
- 장고 마이그레이션은 SQL의 DEFAULT 옵션을 사용하지 않음
- 장고 ORM은 데이터에 대한 제어권을 장고가 전부 가지고 있기를 원함
- ADDFiled가 전달하고자 하는 내용
- makemigrations는 장고가 수행할 DDL 계획을 제안해주는 작업
- ADDField에서 DEFAULT 옵션이 드롭되는 것처럼 장고가 원하는 방식대로 DDL을 계획
- makemigrations로 생성된 마이그레이션 파일이 그 결과물이고 항상 개발자가 기대하는 DDL이 수행되는지 알 수 없기 때문에 개발자는 생성된 마이그레이션 파일을 직접 읽어보고 문제없는지 판단해야함
- 의도하지 않는 DDL이 마이그레이션 파일 내에 계획되어 있다면 이를 커스터마이징 해야 함
- makemigrations는 장고가 수행할 DDL 계획을 제안해주는 작업
- CreateModel
2.4.3 sqlmigrate
<마이그레이션 수행 계획 검토(출력) 명령어)>
- makemigrate를 사용해서 장고에게 DDL 수행 계획 파일을 받았다면 이제 마이그레이션 파일을 검토해야 함
- 앞에서 언급한 것처럼 마이그레이션 Operation들이 수행하는 SQL을 전부 외우는 것은 불필요
- sqlmigrate 명령어는 각 마이그레이션 파일이 수행될 때 발생하는 DDL을 출력해서 개발자에게 보여주는 역할
- sqlmigrate 명령어 사용법
- python manage.py sqlmigrate {장고 앱 이름} {마이그레이션 파일 번호}
- sqlmigrate에서 사용 가능한 옵션
- - - backwards
- 장고의 마이그레이션은 migrate라는 명령어로 수행되는데 - - backwards로 롤백을 수행할 수 있음
- 특정 마이그레이션 파일 수행으로 인해 시스템에 문제가 생겼을 때 데이터베이스를 원상 복구하는 것이 가능함
- 이 옵션을 부여하면 롤백 시 발생하는 DDL을 출력
2.4.4 migrate
<실제 데이터베이스에 마이그레이션을 반영하는 명령어>
- makemigrations를 사용해서 마이그레이션 파일을 생성하고 필요하다면 이를 커스터마이징 해야 함
- sqlmigrate를 사용해서 데이터베이스에서 수행될 DDL을 확인했다면
- 이제는 실제로 데이터베이스에 반영해야함
- migrate는 이름 그대로 데이터베이스에 마이그레이션 파일을 반영
- migrate 명령어 사용법
- python mange.py migrate {장고 앱 이름} {마이그레이션 파일 번호}
- migrate는 마이그레이션 파일 단위로 수행이 가능
- 만약 {장고 앱 이름}만 명시하고 {마이그레이션 파일 번호}를 명시하지 않았다면
- 해당 장고 앱에 존재하는 아직 수행되지 않은 모든 마이그레이션 파일을 수행해서 데이터베이스에 반영
- 만약 {장고 앱 이름}을 명시하지 않고 migrate를 수행한다면
- 해당 장고 프로젝트에 존재하는 아직 수행되지 않은 모든 마이그레이션 파일을 수행해서 데이터베이스에 반영
- migrate에서 사용 가능한 옵션
-
-
- fake: 이 옵션이 부여되면 migrate 수행 시 실제 데이터베이스에 DDL을 반영하지 않고 수행 완료 처리.
- 왜 이런 옵션이 존재하는가?
- → 장고는 자기 자신만 데이터베이스를 완전히 제어할 수 있는 능력을 가지고 있지만 실제 시스템의 데이터베이스에는 장고 이외에 다양한 시스템이 붙어 있는 경우가 많음
-
-
- fake 옵션을 사용해야 하는 상황 예시
- 장고의 제어 범위 밖에서 (예: DBA가 직접 수행) DDL이 반영되었고 이것을 장고에 마이그레이션 이력으로 기록해야 하는 경우
- 조직의 정책이 데이터베이스에 대한 제어권을 DBA가 주도하는 방향으로 운영되어서 모든 마이그레이션 파일을 - - fake 처리 해줘야 하는 경우
- 시스템 성능에 큰 영향을 줄 수 있는 DDL Optimizing과 분할 수행이 필요한 경우
- PostrageSQL에는 DDL 수행 시 하나라도 실패하면 데이터베이스가 알아서 롤백해주는 기능이 존재하지만 MySQL의 경우 이러한 기능이 없음. 따라서 특정 마이그레이션 파일이 수행되다가 중간에 에러가 발생한다면 해당 마이그레이션 파일을 - - fake 처리해주고 데이터베이스에 접근해서 나머지 DDL을 직접 수행해야함
-
-
-
- 마이그레이션 파일 수행 중 에러 발생 시 🚨
- 개발자라면 이른바 삽질을 해봐야 한다..
- 또는 이러한 상황을 최대한 방지하기 위해 MySQL보다는 PostgreSQL을 사용하는 것을 추천
- PostgreSQL은 DDL 수행 시 마이그레이션 파일 단위로 트랜잭션을 보장
- → migrate가 수행 중 실패하더라도 문제를 수정하고 실패한 마이그레이션 파일을 재수행할 수 있음
- —plan: migrate 수행 계획을 출력해줌.
- sqlmigrate와 차이점
- sqlmigrate: DDL을 직접 출력
- migrate - - plan: 장고 operation의 수행 계획을 출력
- 수행 예시
- python manage.py migrate study_example_app --plan
- 거의 사용되지 않는 명령어
- sqlmigrate와 차이점
2.4.5 showmigrations
<마이그레이션 이력 조회하기>
- migrate 명령어를 수행하기 전이나 수행한 이후 지금까지 수행한 마이그레이션 이력을 확인하고 싶을 때 사용
- 지금까지 수행된 마이그레이션 파일과 아직 실행되지 않은 마이그레이션 파일을 검토해주는 역할
- 수행 예시
- python mange.py showmigrations
- 명령어 수행 시 출력되는 결과에서 X 표시가 되지 않은 마이그레이션 파일은 아직 수행되지 않은 파일이라는 의미
- showmigrations로 migrate를 수행하면 study_example_app의 002 파일이 데이터베이스에 반영될 것이라는 예측을 할 수 있음
- showmigrations과 sqlmigrate는 단순 조회 용이기 때문에 여러 번 수행해도 시스템에 변화를 주지 않음
2.4.6 squashmigrations
<마이그레이션 이력 통합하기>
- 장고 프로젝트를 오랜 기간 운영하다 보면 마이그레이션 파일이 너무 많이 쌓이게 됨
- 굳이 알지 않아도 되는 정보도 존재
- 이때 squashmigrations을 사용
- 여러 개의 마이그레이션 파일을 1개의 마이그레이션 파일로 합쳐주는 명령어
- 명령어 사용법
- 특정 장고 앱에 존재하는 마이그레이션 파일을 1부터 2까지 1개의 마이그레이션 파일로 만듦
- python manage.py squashmigrations {장고 앱 이름} {마이그레이션 파일 번호 1} {마이그레이션 파일 번호 2}
- sqashmigrations에서 사용 가능한 옵션
-
-
- squashed -name
- 해당 옵션과 함께 문자열을 부여하면 (squshmigrations - - squashed - name squashed_file) 합쳐진 마이그레이션 파일 이름으로 사용됨
-
-
2.4.7 커스텀 마이그레이션 파일 작성하기
- 데이터 마이그레이션
- 마이그레이션 오버라이딩
'django' 카테고리의 다른 글
모델링과 마이그레이션 (2) (2) | 2025.01.15 |
---|---|
모델링과 마이그레이션 (1) (2) | 2025.01.15 |
장고에 대하여 (4) | 2025.01.07 |
3 - ORM과 Django Rest Framework (1) (1) | 2024.05.23 |
2 - Django Template과 Model (3) | 2024.05.22 |