Django Docs | Migrations - 3

Jihun Kim·2022년 3월 7일
0

Django Docs

목록 보기
2/9
post-thumbnail
post-custom-banner

Initial Migrations

initial migrations는 앱의 테이블의 첫 번째 버전을 생성하는 것을 뜻한다. 가끔 복잡한 모델의 경우 2개 이상의 initial migrations를 갖기도 한다.

initial migrations는 Migration 클래스 내에 initial = True 속성으로 표시된다. 만약 이 속성이 없는데 첫 번째 마이그레이션에 해당하는 경우 해당 마이그레이션은 initial migrations로 간주 된다.


migrate --fake-initial

--fake-initial 옵션을 추가하면 initial migrations는 조금 특별하게 취급된다.

  • 만약 initial migration이 한 개 이상의 테이블을 생성하는 경우(이 때는 operation 리스트에 CreateModel 원소가 들어간다) 장고는 해당 테이블이 DB에 이미 존재하는 지 여부를 체크한다.
    - 만약 존재한다면 이 때는 --fake-initial 옵션에 의해 fake-applies를 하게 된다.
  • 위와 유사하게, 하나 이상의 필드를 추가하는(이 때는 operation 리스트에 AddField 원소가 들어간다) initial migration의 경우 장고는 해당하는 컬럼이 이미 존재하는 지 여부를 미리 살펴본 다음 fake-applies migration을 한다.

테이블이 존재하는 앱에 --fake-initial 이용해 migrations 추가하기

만약 사용자가 만든 앱에 이미 모델과 데이터베이스 테이블은 있지만 migrations는 없는 상황이라고 가정해 보자. 그러면 아래 명령어를 통해 해당 앱이 마이그레이션을 사용하도록 만들 수 있다.

$ python manage.py makemigrations your_app_label

이렇게 initial migration을 생성하고 나면 일반적으로 테이블이 없는 경우 python manage.py migrate를 실행하지만 지금처럼 테이블이 이미 생성되어 있는 상태인 경우 python manage.py migrate --fake-initial를 실행하면 된다.

이 명령어를 실행하면 장고는 이 앱이 이미 initial migration과그에 해당하는 테이블을 이미 가진 상태이며 migration이 이미 적용되었다고 마크해 놓을 것이다. 즉, 테이블이 실제 생성되지는 않았지만 장고가 알아서 migrate이 되었다고 표시해 준다는 것이다.

migrate를 할 때는 아래 두 가지를 주의해야 한다.

  • 테이블을 만든 이후 model을 변경하지 않은 상태여야 한다.
    - migration이 작동하려면 일단 initial migration을 생성하고 변경내역을 만들어야 한다.
    - 왜냐하면, 장고는 데이터베이스가 아니라 migration 파일의 변화를 체크하기 때문이다.
  • 데이터베이스를 직접 수정하지 않은 상태여야 한다.
    - 장고는 기본적으로 데이터베이스가 모델과 일치하지 않다는 사실을 알아서 인지하지 못한다. 그렇기 때문에 데이터베이스를 직접 수정한 상태인 경우 makemigration을 실행하면 테이블을 수정하려 한다는 에러 메시지만 뜨게 될 것이다.
    - 다시 말해, 테이블 생성을 위해서 장고에서는 꼭 initial migration을 통해 initial migration 파일을 생성하는 단계를 거쳐야 한다.


History consistency

migratioin 의존성을 수정할 때 가끔씩 migration은 적용 되어 있지만 이의 dependencies는 적용되지 않은 일관적이지 않은 상태가 될 때가 있다.
이는 곧 dependencies가 바르게 설정 되지 않았다는 것을 뜻하며 이에 따라 장고는 해당 사항이 수정될 때까지 migration을 실행하거나 만들기를 거부하게 된다.
이 때 만약 여러 개의 데이터베이스를 사용하는 경우(default, custom 등등) allow_migrate() 설정을 사용해 migration을 실행시킬 수 있다. makemigrations 실행하도록 함으로써 일관된 history를 만들 수 있다.



Reversing migrations

만약 현재 books 앱에 0003까지 migration이 적용되어 있다고 해보자.
이전 마이그레이션으로 되돌리고 싶다면 0002로 migrate를 하면 된다.
그런데 만약 books 앱의 모든 마이그레이션을 되돌리고 싶다면 아래 명령어를 실행하면 된다.

$ python manage.py migrate books zero
Operations to perform:
  Unapply all migrations: books
Running migrations:
  Rendering model states... DONE
  Unapplying books.0002_auto... OK
  Unapplying books.0001_initial... OK

하지만 되돌릴 수 없는 migration도 있다. 이 경우 migration을 되돌리려 하면 IrreversibleError가 발생한다.

$ python manage.py migrate books 0002
Operations to perform:
  Target specific migration: 0002_auto, from books
Running migrations:
  Rendering model states... DONE
  Unapplying books.0003_auto...Traceback (most recent call last):
django.db.migrations.exceptions.IrreversibleError: Operation <RunSQL  sql='DROP TABLE demo_books'> in books.0003_auto is not reversible


Model Managers

migrations로 managers를 필요에 의해 직렬화(serialize)할 수 있다.
이를 위해서는 Manager class에 use_in_migrations를 정의하면 된다(boolean이다).

class MyManager(models.Manager):
    use_in_migrations = True

class MyModel(models.Model):
    objects = MyManager()

직렬화란?

  • 직렬화란 객체를 바이트 스트림으로 바꾸는 것, 즉 객체에 저장된 데이터를 스트림에 쓰기(write) 위해 연속적인(serial) 데이터로 변환하는 것이다.
  • 직렬화를 통해 객체를 상태 그대로 저장할 수 있으며, 필요할 때 다시 꺼내서 사용할 수 있다.
    - 다시 꺼낼 때 사용되는 것이 역직렬화(de-serialization)이다.
  • 역직렬화는 네트워크나 영구 저장소에서 바이트 스트림을 가져와서 객체가 저장되었던 상태 그대로 변환하는 것을 말한다.

여기에 잘 설명 되어 있다.

profile
쿄쿄
post-custom-banner

0개의 댓글