django

파이썬 장고 마이그레이션 - makemigrations, migrate, reversing migrations

carrotweb 2024. 10. 27. 22:21
728x90
반응형

장고 기반 프로젝트를 처음 실행하면 터미널(Terminal)에 다음과 같이 붉은색으로 마이그레이션(Migration)에 대한 경고를 보여줍니다.

 

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

 

번역하면 적용되지 않은 마이그레이션이 18개 있습니다. 당신의 프로젝트가 앱(admin, auth, contenttypes, sessions)에 대한 마이그레이션을 할 때까지 제대로 작동하지 않을 수 있습니다.

적용하려면 'python manage.py migrate'을 실행하세요.

 

경고가 발생한 이유는 장고 기반 프로젝트는 기본적으로 관리자 기능이 함께 제공되기 때문입니다. 그래서 관리자 앱(App)에 있는 모델(Model)들과 연동되는 테이블(Table)이 데이터베이스(Database)에 있어야 합니다.

 

장고 관리자 앱(admin, auth, contenttypes, sessions)은 어디에 있나요?

 

config 폴더에 있는 settings.py 파일에서 INSTALLED_APPS에 설정되어 있습니다.

 

관리자  앱들은 myenv(가상환경) > Lib > site-packages > django > contrib 폴더에 있습니다.

 

그리고 모델(model)들은 앱(admin, auth, contenttypes, sessions) 폴더에 있는 models.py 파일에 있습니다. (messages, staticfiles 앱에는 모델이 없습니다.)

 

4개의 앱에 있는 모델 클래스가 18개 있습니다. 그래서 마이그레이션 대상이 18개가 있다고 한 겁니다.

 

마이그레이션에 대한 내용 아래에서 자세히 다루겠습니다.

 

그럼 데이터베이스는 어디서 설정해야 할까요?

 

데이터베이스에 대한 설정은 config 폴더에 있는 settings.py 파일에서 DATABASES에 SQLite3로 설정되어 있습니다.

 

왼쪽 EXPLORER를 보면 db.sqlite3 파일이 추가된 것을 확인할 수 있습니다.

이 추가된 db.sqlite3 파일이 데이터베이스로 사용될 파일입니다.

 

SQLite3는 Python에 포함되어 있어 별도로 설치할 필요가 없습니다. 그래서 개발할 때 편리하게 사용할 수 있습니다.

 

만약, 데이터베이스를 MariaDB, MySQL, PostgreSQL로 변경하실 경우에는 settings.py 파일에서 DATABASES를 변경하고 싶은 데이터베이스로 변경하시면 됩니다.

 

그럼 마이그레이션을 통해 데이터베이스에 관리자 테이블들을 생성해 보겠습니다.

 

마이그레이션을 하기 위해서는 마이그레이션 파일(마이그레이션 클래스가 있는 파일)을 생성해야 합니다.

 

마이그레이션 클래스는 앱(app)에 모델(model)이 추가되거나 변경되었을 때 데이터베이스에 테이블을 추가, 수정, 삭제하거나 테이블의 컬럼을 추가, 수정, 삭제할 수 있게 해 줍니다.

  • 모델이 추가되면 migrations.CreateModel
  • 모델이 수정되면 migrations.AlterModelTable
  • 모델이 삭제되면 migrations.DeleteModel
  • 모델에 필드가 추가되면 migrations.AddField
  • 모델에 필드가 수정되면 migrations.AlterField
  • 모델에 필드가 삭제되면 migrations.RemoveField

마이그레이션 클래스에 대한 더 자세한 내용 장고 문서 사이트를 참고하시기 바랍니다. (https://docs.djangoproject.com/en/5.1/ref/migration-operations/)

 

예를 들어, 모델이 추가되면 마이그레이션 클래스의 오퍼레이션에 migrations.CreateModel 클래스로 테이블과 테이블의 필드를 추가할 수 있습니다. (admin의 LogEntry 모델에 대한 마이그레이션 파일입니다.)

 

예를 들어, 모델이 수정되면 마이그레이션 클래스의 오퍼레이션에 migrations. AlterField 클래스로 테이블의 필드를 수정할 수 있습니다. (auth의 Permission모델에 대한 마이그레이션 파일입니다.)

 

앱(App)에 모델(Model)이 있으면 반드시 모델에 대한 마이그레이션 클래스가 있어야 합니다.

하나의 마이그레이션 파일에는 앱에 있는 모델 수만큼 마이그레이션 클래스가 있어야 합니다.

 

그럼 마이그레이션 클래스를 직접 만들어야 할까요?

아닙니다. 직접 만들 수 있지만 장고에서는 마이그레이션 클래스를 자동으로 생성해 주는 makemigrations 명령어를 지원하고 있습니다.

 

 

makemigrations(메이크 마이그레이션)

 

마이그레이션 클래스를 생성해 주는 명령어인 makemigrations를 터미널(Terminal)에서 실행합니다.

python manage.py makemigrations {앱 이름}

 

(앱 이름}은 모델이 변경된 앱의 이름입니다.

(앱 이름}이 있으면 해당 앱에서만 추가되거나 변경된 모델이 있는지 확인해서 마이그레이션 클래스를 생성해 줍니다.

(앱 이름}이 없으면 전체 앱을 대상으로 추가되거나 변경된 모델이 있는지 확인해서 마이그레이션 클래스를 생성해 줍니다.

 

장고 관리자의 앱(admin, auth, contenttypes, sessions)에 대해 하나씩 실행할 수 있지만 전체 앱을 대상으로 실행하겠습니다.

python manage.py makemigrations

 

makemigrations를 실행하면 터미널(Terminal)에 No changes detected (감지된 변경이 없습니다.)라고 나옵니다.

 

 

왜 장고 관리지 앱에 대해  마이그레이션 클래스가 있는 파일이 생성되지 않았을까요?

마이그레이션 파일을 생성한 적이 없는 왜 변경된 게 없다고 할까요?

 

그 이유는 이미 장고 관리자 앱에는  마이그레이션 클래스가 있는 파일이 생성되어 있고 우리가 관리자 앱에 있는 모델을 수정한 적이 없기 때문입니다.

 

위에서 마이그레이션 클래스를 설명할 때 예시로 보여드린 화면을 보시면 django의 auth 앱에 migrations 폴더에서 마이그레이션 파일들이 있는 것을 볼 수 있습니다.

 

다음은 django의 contenttypes 앱에 migrations 폴더에 있는 마이그레이션 파일입니다.

 

위와 같이 앱에 모델이 있을 경우 makemigrations를 실행하면 앱에 있는 migrations 폴더에 마이그레이션 파일이 생성됩니다.

 

예를 들어, test라는 앱을 마이그레이션 한다면 test 앱에 있는 migrations 폴더에 0001_initial.py 파일이 생성됩니다.

python manage.py makemigrations test
test/ --> 앱 폴더
    migrations/ --> 마이그레이션 폴더 (앱 생성시 자동으로 생성됩니다.)
        __init__.py --> 초기화 파일 (파일에 내용은 없습니다. 앱 생성시 자동으로 생성됩니다.)
        0001_initial.py --> 처음 생성된 마이그레이션 파일

 

__init__.py 파일은 마이그레이션을 초기화하기 위해서 생성되는 파일입니다.

 

생선 된 마이그레이션 파일 명을 보면 앞에 0001_처럼 번호가 있는 것을 볼 수 있습니다.

이 번호는 makemigrations를 실행할 때 앱의 모델이 추가되거나 변경된 것이 있으면 자동으로 번호가 증가하여 마이그레이션 파일 명에 추가됩니다.

 

다음처럼, auth 앱은 처음 마이그레이션(0001_initial.py) 한 후 11번을 수정(0012_alter_user_first_name_max_length.py) 한 것을 알 수 있습니다.

 

이 번호는 또한 마이그레이션을 이전 상태로 변경하고 싶을 때 사용됩니다.

 

그럼 생성된  마이그레이션 파일을 통해 마이그레이션을 실행해 보겠습니다.

 

 

Migrate(마이그레이트)

 

마이그레이션을 실행 주는 명령어인 migrate를 터미널(Terminal)에서 실행합니다.

python manage.py migrate {앱 이름} {마이그레이션 번호}

 

(앱 이름}은 마이그레이션을 할 앱의 이름입니다.

(앱 이름}이 있으면 해당 앱에서만 마이그레이션을 실행합니다.

(앱 이름}이 없으면 전체 앱을 대상으로 마이그레이션을 실행합니다.

 

(마이그레이션 번호}는 마이그레이션을 할 번호입니다.

(마이그레이션 번호}가 있으면 번호로 만들어진 마이그레이션 파일을 실행합니다. (Reversing Migrations - 이전 번호를 입력하면 이전 상태로 되돌아가게 됩니다.)

(마이그레이션 번호}가 없으면 전체 마이그레이션 파일을 실행합니다.

 

Reversing Migrations는 아래에서 설명드리겠습니다.

 

우리는 처음 실행하기 때문에 (앱 이름}과 (마이그레이션 번호}를 입력하지 않고 실행하겠습니다.

python manage.py migrate

 

실행 결과를 보면 장고 관리자의 앱(admin, auth, contenttypes, sessions)에 있는 마이그레이션 파일들이 실행된 것을 알 수 있습니다.

 

DBeaver로 db.sqlite3 파일을 오픈해 보면 장고 관리자 테이블들이 생성된 것을 확인할 수 있습니다.

 

 

Reversing Migrations(리버싱 마이그레이션, 마이그레이션을 이전 상태로 되돌리기)

 

다음처럼, test앱에서 3번의 마이그레이션을 실행했다고 가정하겠습니다.

test/
    migrations/
        __init__.py
        0001_initial.py
        0002_alter_user_name_max_length.py
        0003_alter_user_email_max_length.py

 

여기서 모델에 있는 메일의 길이가 수정할 필요가 없어졌다면 어떻게 해야 할까요?

 

모델에 있는 메일의 길이를 다시 이전 길이로 수정하고 다시 makemigrations를 실행하고 migrate를 실행합니다. (그럼 0004 마이그레이션 파일이 생성되고 실행됩니다.)

또는 이전 마이그레이션(0002)으로 되돌리고 0003 마이그레이션을 삭제합니다.

 

어떤 방식으로 해도 문제는 없습니다.

 

여기서는 이전 마이그레이션(0002)으로 되돌리고 0003 마이그레이션을 삭제해 보겠습니다.

 

마이그레이션을 0002번째로 되돌리기 위해서는 migrate를 실행할 때 test 앱과 0002 번호를 입력하면 됩니다.

python manage.py migrate test 0002

 

그럼 0002번째 마이그레이션으로 변경됩니다.

Operations to perform:
  Target specific migration: 0002_alter_user_name_max_length, from test
Running migrations:
  Rendering model states... DONE
  Unapplying test.0003_alter_user_email_max_length... OK

 

그러고 나서 0003_alter_user_email_max_length.py 파일을 삭제하면 됩니다.

 

마이그레이션 파일을 삭제할 때는 주의를 기울여야 합니다.

왜냐하면, 마이그레이션 파일은 이전 번호 마이그레이션에 의존하게 되어 있습니다.

그래서 중간에 있는 마이그레이션 파일은 임의로 삭제하면 안 됩니다.

 

다음처럼, auth 앱에 마지막 마이그레이션 파일을 보게 되면 dependencies에 "0011_update_proxy_permissions"과 의존하고 있는 것을 확인할 수 있습니다.

 

반드시 이전 번호로 Reversing Migrations 한 후에 마이그레이션 파일을 삭제하시길 바랍니다.

 

마이그레이션에 대한 더 자세한 내용 장고 문서 사이트를 참고하시기 바랍니다. (https://docs.djangoproject.com/en/5.1/topics/migrations/)

 

그럼 테스트로 auth 앱의 마이그레이션을 0011번으로 Reversing Migrations 한 후에 다시 0012번으로 마이그레이션 해보겠습니다.

python manage.py migrate auth 0011

 

python manage.py migrate auth 0012

728x90
반응형