Ethan Hur's blog

Django ORM default 값

2018-01-09

요즘 회사에서 Django 를 사용하고 있다.

Django 의 경우에는 자체적으로 ORM 을 사용하고 있는데, ORM의 default 값 때문에 삽질한 로그를 적어본다.

django model 을 다음과 같이 선언한다.

1
2
3
4
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100, default="")

이렇게 선언을 한 뒤, DB migration 을 하게 되면 테이블에 default 값이 없는 것을 확인할 수 있다.

심지어 이게 오류인가 싶어 SQL 문을 뽑았더니 SQL문에서 DEFAULT 값을 설정한 다음 바로 DROP DEFAULT 를 하는 게 아닌가!

이러한 이상한 점이 있어서 구글신을 찾았더니 다음과 같은 이슈를 찾았다.

https://code.djangoproject.com/ticket/28000

나와 같은 이슈를 발견한 사람이 있어 살펴보았더니 다음과 같이 써져 있다.

Django’s ORM don’t use defaults defined at the database level and always specify the value when performing inserts instead.

이러한 이유를 명확히 하기 위해 Django 문서를 뒤졌더니 힌트를 발견했다.

https://docs.djangoproject.com/en/2.0/ref/models/fields/#default

이 링크의 내용을 살펴보면,

The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.

default 값이 callable object 를 지원한다는 점이 중요했다. 예를 들어 로그를 남긴다고 가정해보자. host를 남기는 컬럼이 있을테고 그것을 default=get_host() 로 해두면, default value 를 추상화 시키는 효과를 얻게 된다.

그리고 난 Mysql 밖에 사용을 안해봤지만, 다른 DB 엔진들과의 종속성으로 생기는 각종 골치아픈 이슈, 버그들을 제거하기 위해 이런 식의 구조를 택했을 것 같다.

그리고 저기 이슈에 적혀진 저 내용은 Django 1.x 에서 발생하는 버그로, 2.0 에서는 고쳐진 것 같다.

정리

  1. Django ORM은 DB 종속성을 제거하고 추상화 시키기 위해 database level default value 를 사용하지 않음.

  2. 그럼에도 불구하고 Django 1.x 버전에서는 DEFAULT 값을 만든 다음 DROP DEFAULT 를 하는 경우가 있는데, 이는 버그임

Django 같은 프레임워크에 이런 버그가 있다는 게 신기하다

Tags: Django