❓Django migrations 집중 탐구

yeeun lee·2020년 4월 3일
4

Django

목록 보기
2/8

Django의 models.py에서 class를 통해 테이블의 형식을 만들고, migrate하는 과정에 너무 이해가 안 되어서 따로 정리했다.

그냥 전체 페이지에다 담으려니 너무 내용 강조도 안 되고 모르는 단어도 있어서 ... 여기에 검색한 내용을 포함해서 엄청 자세하게 다뤄보고 이해해보자 😤😤😤😤

1. docs.django

일단 django 공식 문서에서 정의한 migration 관련 내용을 보자.

migrationsmodels.py에서 바꾼 내용을(예를 들면 field를 추가하거나, model을 삭제하는 것 등) 데이터베이스 스키마에 전파시키는 장고의 방법이다. 일반적으로 겪는 문제가 언제 migrations를 하고, 언제 실행 하는지에 대한 부분이기 때문에 꼭 알아두자!

공식 문서에서는 migrations를 데이터베이스 스키마의 버전 컨트롤 시스템으로 생각하라고 말한다. (You should think of migrations as a version control system for your database schema.) 내 모델에 적용된 변화를 모아서 각 migrations files에 적용시켜주는 것이기 때문이다. git commit과 유사하다.

그리고 migrate는 내 데이터베이스에 변화된 내용을 실제 테이블에 적용해주는 것이다. 각 app 안에 있는 migrations file은 해당 app 안의 migrations 디렉토리 안에 존재하고, commited 되어 코드로서 분배되도록 디자인되어있다.

- command

  • migrate : migrations를 적용하거나 적용 해제(applying or unapplying)한다.
  • makemigrations : models에 적용한 변화를 기반으로 새로운 migrations를 만들어낸다.
  • sqlmigrate: migration을 위한 SQL statements를 보여준다.
  • showmigrations: project의 migrations list와 그들의 상태(체크박스)를 보여준다.

- schema?

컴퓨터 과학에서 데이터베이스 스키마(database schema)는 데이터베이스에서 자료의 구조, 자료의 표현 방법, 자료 간의 관계를 형식 언어로 정의한 구조이다.

데이터베이스 관리 시스템(DBMS)이 주어진 설정에 따라 데이터베이스 스키마를 생성하며, 데이터베이스 사용자가 자료를 저장, 조회, 삭제, 변경할 때 DBMS는 자신이 생성한 데이터베이스 스키마를 참조하여 명령을 수행한다.

위키피디아 영문판 첫 줄만 기억하자. 스키마는 fomal language로 묘사되고 데이터베이스관리시스템이 뒷받침해주는 데이터베이스의 구조다.

The database schema of a database is its structure described in a formal language supported by the database management system (DBMS).

2. command 자세히 보기

위 공식 문서의 정의에서 알 수 있듯, migrations 파일은 models.py에서 변화된 테이블 정보를 manage.py의 makemigrations 옵션을 통해 저장하는 디렉토리이다. 이제 명령어 실행에 대해 조금 더 자세히 알아보자.

(대부분의 명령어는 python manage.py command 와 함께 실행되어 소제목에서는 생략했다.)

- makemigrations

django migrations 디렉토리에 파일을 만드는 명령어. models.py에서 class를 만들고 makemigrations를 하면 migrations에 0001.initial.py 파일이 생긴다.

❯ python manage.py makemigrations
Migrations for 'myapp':
  myapp/migrations/0001_initial.py
    - Create model Users

python manage.py makemigrations 는 내가 models.py에서 만든 각 class를 테이블을 만드는 SQL command로 만들어준다.

- migrate

이제 변경 사항이 저장된 migrations 파일을 가지고 실제 db에 적용하는 단계다. 처음으로 migrate를 하면 root directory에 db.sqlite3 라는 폴더가 생기고, sqlite3을 치면 데이터베이스에 접속할 수 있다. 변경 사항을 테이블에 적용할 때 특정 앱을 지정해서 migrate를 할 수도 있다.

아래는 앱을 지정하지 않아 내가 app에서 만든 models 외에 모든 내장 앱의 migrations들이 migrate되었다. (=변경 사항이 적용되었다)

❯ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, myapp, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
import json
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK

  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
"""mine URL Configuration
  Applying myapp.0001_initial... OK
  Applying sessions.0001_initial... OK

그러니까 migrate는 migraions에서 만들어진 SQL command를 사용해서 데이터베이스에 테이블을 만드는 것이라고 보면 된다.

- show migrations

migrate한, 즉 변경 사항을 적용한 파일들을 보여준다. X로 체크된 것들이 모두 migrate가 완료된 데이터파일들이다.

❯ python manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
myapp
 [X] 0001_initial
sessions
 [X] 0001_initial

- sqlmigrate

migration을 위한 SQL statements를 보여준다. 어떤 기능을 실행하는 명령어는 아니고, 내가 django에서 class를 통해 생성하거나 변경한 table이 SQL command로 어떻게 표현되는지 보여주는 기능인 것 같다.

❯ python manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" integer NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;

3. migrate와 migrations의 차이

migrations는 변경 내용을 저장하고, migarte는 그 내용을 테이블에 적용시킨다.
git의 commit, merge와 비슷한 개념으로 이해하면 좋을 것 같다 (공식문서에도 commit과 유사하다고 하기도 했고)

  1. makemigrations는 내장 앱이나 새로 만든 앱의 SQL command를 생성한다. 하지만 변경 사항만 저장할 뿐이지 내 데이터베이스에서 실행되는 것은 아니다. 그래서 makemigrations를 한 뒤에 테이블이 생기거나 하지 않는다.

  2. 1번 뒤에 sqlmirate를 하면 makemigrations를 통해 생성된 것들을 모든 SQL commands를 볼 수 있다.

  3. migrate는 2번의 SQL commands를 데이터베이스 파일에서 실행한다. 그래서 migrate를 하고 나면 내 데이터베이스 파일 안의 앱의 테이블들이 생성된다. migrate command를 실행하고 db.sqlite3를 실행하면 모든 테이블이 생긴 것을 볼수 있을 것이다.

profile
이사간 블로그: yenilee.github.io

0개의 댓글