규도자 개발 블로그

Django로 개발할 때 꼭 주의해야할 점 본문

Python/Django

Django로 개발할 때 꼭 주의해야할 점

규도자 (gyudoza) 2020. 2. 13. 15:39

Django로 개발할 때 꼭 주의해야할 점

django로 개발할 때 편한 점이라고 하면 어플리케이션 개발환경을 구축할 때 기본적으로 sqlite를 만들어줘서 개발하려는 컴퓨터에 DB server를 따로 만들어 연결하지 않고도 개발에 착수할 수 있다는 점인데 이게 치명적으로 작용할 수 있다. 이유는 바로 Django의 Queryset이 DB에 의존적이기 때문이다.

 

Django는 생쿼리를 되도록이면 자제하는 ORM(Object Relational Mapping) 프레임워크이다. 근데 아이러니하게도 이 ORM이라는 정체성을 갖게 해주는 Queryset이(예: Post.objects.all()등으로 얻는 모든 객체) DB에 의존적이다. 그러니까 작성된 명령어에 따라 sqlite에서는 이렇게, mysql에서는 저렇게, postgresql에서는 지맘대로 작동할 수가 있다는 것이다.

 

아주아주아주 간단한 예를 들자면 queryset의 조건문 중 하나인 contains를 들 수가 있는데 django 공식문서의 queryset api references문서를 보면(왼쪽 링크 클릭 후 'icontains'찾기) SQLite users에게 경고하는 문구가 뜨는데

 

SQLite는 대소문자구분기능을 지원하지 않으니 contains와 icontains가 똑같이 작동한다.

 

는 말이 있다. contains는 조건문으로 들어오는 문자열이 포함된 결과를 찾는 조건문이지만 대소문자를 구분하고 icontains는 구분하지 않는다.

 가장 대표적인 예로 위를 들었지만 이밖에도 조건검색으로 튀어나온 queryset을 자기마음대로 소팅하고 정렬하고 자르고 붙이는 과정에서도 다르게 작동할 수 있다. 이건 내 경험에서 비롯돼 피와살이 된 경우인데 SQLite에서는 멀쩡하게 잘 되던 정렬기능이 잘 안되어 결과값을 살펴보니 Postgresql과 SQLite에서 해당 부분을 처리하는 로직이 달라 같은 코드라고 하더라도 다르게 작동하는 것이었다. 개발용 컴퓨터는 최대한 라이트하게 가져가려고 DB Server를 하나도 설치하지 않으려고 했었는데 피를 본 경우라고 해야할까.

 조금 더 구체적으로 설명하자면 SQLite에서는 filtering한 Queryset에 배열의 인덱스([0], [1])를 붙여서 원하는 값을 쉽게 가져왔지만 이상하게 Postgres에서는 분명 각각의 위치에 다른 데이터가 들어있었음에도 불구하고 인덱스를 달리 줘도 같은 데이터를 출력했다. 결국 queryset을 filtering할 때 oder_by('pk')를 붙이는 임시방편으로 해결하긴 했지만 황당한 경험이 아닐 수 없어 기억에 많이 남는다.

 

그런고로, Django가 SQLite를 지원한다 하더라도 복잡한 소팅, 리스팅, 필터링 로직을 가진 앱이라면 꼭! 상용화할 때 쓸 DB로 직접 사용해가며 개발하는 것을 권고하는 바이다. 그래도 싫다면 SQLite로 개발하다가 상용단계로 넘어가려고 할 때 미리미리 DB를 바꿔서 QA목록을 점검한 뒤에 진행하는 것이 좋을 것이고. 아무튼 개발환경은 개발환경일 뿐이다.

Comments