ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Django] Migration 기능
    언어/파이썬 & 장고 2019. 8. 31. 21:27

    장고의 명령어 중, migrate, makemigrations 와 같은 명령어가 있습니다. 이러한 명령어는 models.py에 정의된 모델의 생성/변경 내역을 히스토리 관리데이터베이스에 적용 등과 같은 기능을 제공하여 손쉽게 데이터베이스의 구조를 바꿀 수 있습니다.

    Migration 관련 명령어

    # 마이그레이션 파일 생성
    $ python manage.py makemigrations <app-name>
    
    # 마이그레이션 적용
    $ python manage.py migrate <app-name>
    
    # 마이그레이션 적용 현황
    $ python manage.py showmigrations <app-name>
    
    # 지정 마이그레이션의 SQL 내역
     python manage.py sqlmigrate <app-name> <migration-name>

    makemigrations

    $ python manage.py makemigrations test
    
    Migrations for 'test':
      test/migrations/0001_initial.py:
        - Create model Choice
        - Create model Question
        - Add field question to choice


    makemigrations을 실행하면 모델을 변경시킨 사실 또는 새로 생성한 모델들과 같은 변경사항을 migrations로 저장하고자 Django에게 알려줍니다. migration은 Django가 모델의 변경사항을 저장하는 방법으로써, 디스크상의 파일로 존재합니다. 원한다면, <app-name>/migrations/0001_initial.py 파일로 저장된 새 모델에 대한 migration을 읽어볼 수 있습니다. 또 수동으로 Django의 변경점을 조정하고 싶을 때 직접 변경할 수 있습니다.


    migration들을 실행시켜주고, 자동으로 데이터베이스 스키마를 관리해주는 migrate 명령어가 있습니다. 이 명령을 알아보기 전에 migration이 내부적으로 어떤 SQL 문장을 실행하는지 살펴봅시다. sqlmigrate 명령은 migration 이름을 인수로 받아, 실행하는 SQL 문장을 보여줍니다.

    migrate

    $ python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, test, sessions
    Running migrations:
      Rendering model states... DONE
      Applying test.0001_initial... OK


    적용되지 않은생성/변경된 migrations들의 파일을 데이터베이스에 적용합니다. 이때 Django는 django_migrations 테이블을 두고 마이그레이션 적용 여부를 추적합니다. 이를 사용하면 데이터베이스를 직접 접근하지 않고도 모델의 반복적인 변경을 가능하게 해줍니다. 이처럼 마이그레이션을 만드는 명령과 적용하는 명령이 분리된 것은 버전 관리 시스템에 마이그레이션을 커밋하고 앱과 함께 출시할 수 있도록 하기 위해서라고 장고 공식 문서에 나와 있습니다.

    모델의 생성/변경을 적용하는 단계는 아래와 같습니다.

    1. models.py 추가 및 변경
    2. python3 manage.py makemigrations를 실행해 변경사항에 대한 마이그레이션 파일 생성
    3. python3 manage.py migrate를 실행해 변경사항을 데이터베이스에 적용

    showmigration

    현재 적용된 마이그레이션 파일을 보여줍니다. 

    $ python manage.py showmigrations
    
    auth
    [ ] 0001_initial
    [ ] 0002_alter_permission_name_max_length
    [ ] 0003_alter_user_email_max_length
    [ ] 0004_alter_user_username_opts
    [ ] 0005_alter_user_last_login_null
    [ ] 0006_require_contenttypes_0002
    [ ] 0007_alter_validators_add_error_messages
    [ ] 0008_alter_user_username_max_length
    contenttypes
    [ ] 0001_initial
    [ ] 0002_remove_content_type_name
    sessions
    [ ] 0001_initial


    sqlmigrate

    생성된 migrations파일들이 어떤 sql 문장을 실행하는지 보여줍니다.

    $ python manage.py sqlmigrate test 0001
    
    BEGIN;
    --
    -- Create model Choice
    --
    CREATE TABLE "test_temp" (
    "id" serial NOT NULL PRIMARY KEY,
    "name" varchar(200) NOT NULL
    );
    --
    -- Create model Question
    --
    CREATE TABLE "test_temp2" (
    "id" serial NOT NULL PRIMARY KEY,
    "name" varchar(200) NOT NULL
    );
    --
    -- Add field question to choice
    --
    ALTER TABLE "test_temp" ADD COLUMN "temp2_id" integer NOT NULL;
    ALTER TABLE "test_temp" ALTER COLUMN "temp2_id" DROP DEFAULT;
    CREATE INDEX "test_temp_7aa0f6ee" ON "test_temp" ("temp2_id");
    ALTER TABLE "test_temp"
    ADD CONSTRAINT "test_temp_temp2_id_246c99a640fbbd72_fk_test_temp2_id"
    FOREIGN KEY ("temp2_id")
    REFERENCES "test_temp2" ("id")
    DEFERRABLE INITIALLY DEFERRED;

    COMMIT;

    만들어진 migrations의 sql은 아래와 같은 규칙이 있습니다.

    1. 테이블의 이름은 앱의 이름과 모델의 이름(소문자)가 조합되어 자동으로 생성. 위의 예시는 test 앱과 temp, temp2 모델명이 합쳐진 케이스
    2. 만약 pk가 지정되어 있지 않으면 자동으로 id라는 컬럼을 생성하고 pk로 지정
    3. 관례적으로 Djanngo는 외래키 컬럼의 마지막에 _id를 자동으로 추가
    4. sqlmigrate 명령어를 실행해도 실제로 데이터베이스의 마이그레이션을 실행하지 않음.


    댓글