코딩 하는 가든

Django - PostgreSQL과 상속 모델의 Sequence (feat. Not Null constraint failed id) 본문

Django

Django - PostgreSQL과 상속 모델의 Sequence (feat. Not Null constraint failed id)

가든리 2020. 3. 18. 01:12

Postgresql과 상속 모델의 Sequence

-  환경 : Django 버전 3.0, PostgreSQL 버전 9.5.20

 

 오늘 겪은 상속 모델에서 생겼던 문제점을 기록해 보고자 한다.

Django 에서는 Model class를 정의 해 두면 데이터 베이스 스키마에 반영 시켜주는 아주 편리한 Migration 기능을 제공 한다. 이 migration 기능이 없었다면 아주 힘든 길을 걷고 있었겠지...

 

 평소와 다름 없이 모델을 추가하고 migrate를 한 뒤 Test 를 진행 하려고 했다. 그런데 무슨일인가 오브젝트 생성이 되지 않았던 것이다. 발생한 에러는 다음과 같다.

Integrityerror : Not Null constraint failed model_id

  응...? 평소와 같이 모델을 만들었는데 id로 null 값이 들어갔다. 무슨 일인고 해서 db스키마를 보니 sequence가 생성이 안되어있었다.

 

 코드를 그대로 가져다 쓰기가 그래서 간단한 예시 코드를 만들어 보았다.

class Toy(models.Model):
    name = models.CharField(max_length=50, help_text='이름')
    price = models.IntegerField(help_text='가격')
    company = models.CharField(max_length=50, help_text='판매사')


class RoboToy(Toy):
    battery_capacity = models.IntegerField(help_text='배터리 용량(mAh)')


class ElectronicCar(Toy):
    battery_type = models.CharField(max_length=10, help_text='건전지 종류')

 위와 같은 코드를 마이그레이션을 했을 때 스키마가 다음과 같이 생성 되었다.

 

PostreSQL 스키마

 

부모 클래스인 Toy 모델은 테이블, 시퀀스가 잘 생성 되었는데 자식 클래스인 RoboToy와 ElectronicCar는 sequence가 없었던 것이다! 왜 그랬을까? 사실 이후로 sqlite3로도 테스트를 해봤는데 sqlite3 에서는 부모, 자식 클래스 모두 테이블과 시퀀스가 정상적으로 생성되었다. (의문...)

 

결론적으로 PostgreSQL 에서는 상속 관계인 모델이 있을 때 자식 클래스의 시퀀스가 생성되지 않는 희안한 문제가 있었다. 설정을 잘못 한 것인지 다른 방법이 있는지 자세히는 모르겠지만 다음과 같이 해결했다.

 

 PostgreSQL에 직접 접속 하여 아래와 같은 코드로 시퀀스를 생성 해주고 auto increment를 설정 해 주었더니 해결 되었다.

CREATE SEQUENCE item_robotoy_id_seq;
ALTER TABLE item_robotoy ALTER COLUMN id SET DEFAULT nextval('item_robotoy_id_seq');