본문 바로가기

Django

Django 속이기 - migration 파일 직접 수정

models.py를 수정한 뒤 makemigration을 했을 때 이런 메세지가 뜰 수도 있다.

 

You are trying to add a non-nullable field <필드명> to <소문자 class 명> without a default; we can't do that 어쩌구

 

이미 있는 model class에 non-nullable인 필드를 추가하면 이런 일이 생긴다. datetime 필드를 추가한 뒤 나왔던 메세지와는 조금 다르다. 그 때는 기존에 존재하는 데이터에게 어떤 시간을 채워넣을까 하는 메세지였는데, 이건 데이터베이스를 이미 삭제한 뒤여도 나온다.

 

동기들에게서 들은, default를 안 주고 해결하는 방법은 두가지였다.

1. null=True를 주고 만들고, not nullable한 필드를 만들고 싶다면 기존 데이터의 해당 column에 값을 넣은 뒤에 null=True를 지우고 다시 makemigration한다.

2. 기존에 존재하는 migration 파일을 전부 지우고 makemigration을 해서 migration 파일을 새로 만들기

주말에 문제를 마주하고 동기들의 설명을 들었을 땐 기억이 안 났었는데, 집에 와서 찬찬히 기억을 되짚어보니 예전에 이런 적이 있었던 것 같다. 두 방법 다 해보았던 거 같다.

 

예전엔 migration 파일을 지우는 걸 주저하지 않았다. migration 파일이 깔끔하게 한두개만 남아있는 게 더 보기 좋다고 생각하기도 했다. 그래서 2번 방법을 주로 사용했다.

그런데 migration 파일도 기록의 일종이라는 걸 듣고 생각이 바뀌었다. 언제 뭐를 수정했는지 알고자 한다면 migration 파일이 0001만 달랑 남아있는 게 아니라 다 남아있어야 된다. 그리고 git을 통해 협업을 한다면 migration파일도 공유하고 있기 때문에, 이 파일들을 지우고 새로 만든다면 conflict가 많이 난다. 같은 수정내역이 든 같은 번호의 migration 파일이어도 파일 안에 생성 일시 라인이 있기 때문에 conflict가 난다.

기존 migration 파일을 보존하고자 1번 방법을 사용하면 not nullable한 필드를 추가하는 과정에서 군더더기가 남는다. null=True를 빼는 수정사항만 남은 migration 파일 같은 것...

 

그래서 migration 파일 직접 수정에 도전해보았다. migration 파일을 새로 만들지 않고 마치 기존에 있는 migration 파일 내용에 이게 원래 있었던 것처럼! DB를 밀어둔 상태에서 branch를 따로 파서 작업했다.

migration 파일들끼리도 의존성이 있기 때문에 대충 보고 수정하면 파국이다... 결국 다 지우고 다시 만들어야 되는 경우가 생긴다.

그리고 이 방법도 다른 방법들과 마찬가지로 DB를 백업해둔 게 있어야 안전하다.

 

makemigrations했을 때 에러가 뜨면 일단 2를 눌러 나간다.

에러를 일으킨, 새로 추가하려는 필드가 들어있는 app 폴더 내의 migrations 폴더에 들어간다. 그리고 이 안에 있는 migration 파일에 의존하는 다른 app의 migration 파일이 있는지 다 뒤진다. 이 app 내에서 migration 파일들 끼리의 의존성 관계도 파악해야 된다. 만일 migration 파일 숫자가 많을 경우 이러다 시간을 더 소모할 수도 있다.

의존성면에서 안전하다 생각하는 파일을 하나 골라잡아 열면 이렇게 생겼다.

accommodationImage에 room 필드가 없는 상태

수정한 model에 맞게 migration 파일을 수정해준다. room 필드를 추가했다.

(좌) migration 파일 / (우) models.py

이런 식으로 변경 사항 조작 다 한 뒤에 migrate

 

더 공부할 것

1. 이번에는 db를 밀어둔 상태에서 migration 파일을 수정했다. 기존 DB가 있는 상태에선 어떻게 될까?

2. 이렇게 조작하는 거 말고 그냥 장고 메세지에서 제시하는 대로 default를 줘가면서 만드는 게 정상인 건 아닐까? database를 안전히 보존하려면.. -> 실무에선 이게 맞다고 한다.