[Django] Model에 Field 추가시 주의사항
Model에 Field를 추가하는 상황
기존 모델에 필드를 추가해야 하는 경우각 있다. 기존 데이터베이스에 데이터가 없다면 상관 없겠지만 이미 데이터가 있다면 필드를 추가하는 데 있어 여러 고민이 생긴다.
나는 앞서 title, rating 두 컬럼만 가진 Book 객체에 2개의 데이터를 넣었다. 그리고 author, is_bestselling 객체를 추가하여 migration 파일을 다시 재정의 하려고 한다.
그러자 나는 아래와 같은 응답을 받았다. 간단히 요약하자면 새로운 컬럼에 대한 default 값이 정의되어 있지 않아 기존 데이터(existing rows)에 어떤 값을 넣어야 할지 모르겠다는 것이다. 그리고 옵션을 Select 하라고 한다.
- 기존에 존재하는 모든 데이터들에 신규 컬럼에 대해 null 값을 넣는다. (신규 컬럼에 대한 nullable을 허용하는 경우)
- 일단 Quit 하고 models.py를 수정한다.
1번은 즉시 처리할 수 있겠지만, 해당 상황을 모르는 다른 팀원이 보았을 때는 맥락을 이해하지 못할 수도 있다. 따라서 일단 나와서 models.py에서 null 값을 허용하거나 default value를 넣어주는 것이 조금 더 이상적인 대답으로 보인다.
Model 수정하기
null & default
Field의 파라미터에는 null과 default가 있다. 두 방법 모두 데이터베이스를 수정 할 수 있는 방법으로 쓸 수 있다. 두 방법은 배타적인 관계가 아니다. 무슨 말이냐면, 두 방법의 교집합(null & default)로 넣을 수도 있다는 것이다. 해당 경우에는 당연시 default value가 들어가겠지만, 차후 데이터를 넣을 때 null 값도 허용한다는 의미이다.
** null 파라미터의 default value는 false이다.
** default 파라미터의 default value는 NOT_PROVIDED (django에서 정의한 pass하는 Empty Class)이다.
이러한 것에 대한 설계는 파이썬(django)의 app 측면이 아닌 DB의 모델링 관점에 더욱 가깝다. 잘 설계된 DB 모델링은 차후 데이터베이스의 관리와 맞닿아 있고, 많은 기업들이 잘 설계된 모델링에 입각하여 애플리케이션을 구현하려는 이유이기도 하다. (DB 전문 회사에 있다 보니 어느 DBA 임원 분의 강의를 들었는 데.. 이 때문에 DBA와 Application 개발자가 맨날 다툰다고 한다.. ㅎㅎ..) 여튼 우리는 두 개다 가능한 옵션이며, 배타 관계가 아님을 염두에 둬야 한다.
is_bestselling = models.BooleanField(null=True)
is_bestselling = models.BooleanField(default=True)
is_bestselling = models.BooleanField(null=True, default=True)
null vs. blank
우선 공통점에 대해 말해보자 한다. 어떤 값에 대한 입력을 넣지 않았을 때, 두 경우 모두 해당 상황을 처리 할 수 있다. null은 null로 표시를 하고, blank는 "" (아무 입력값 없음)으로 표시된다.
하지만 null과 blank는 활용해야 할 경우가 다르다. 예를 들어 날짜 필드 처럼 특정 포맷이 갖춰지거나 숫자 필드와 같은 경우, 공백(blank)을 저장하는 것이 올바른 옵션이 아니다. 그것은 분명히 잘못된 데이터 유형이기 때문이다. 이런 경우는 분명하게 null을 사용해주어야 한다. 참고로 django에서 기본적으로 null을 허용하지 않기 때문에 명시적으로 null=true 옵션을 주어야 한다.
반대로 일반적인 문자열을 받는 필드라면 null 보다는 blank가 조금 더 괜찮다. charField나 emailField 처럼 입력값을 생략하고 null로 표기하기 보다는 공백으로 표기함으로써 입력값이 들어온 다른 문자열과 비교해 보았을 때 타입의 통일감이 있다. 공백도 결국은 문자열이기 때문이다.