일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 영어원서읽기
- 잡생각
- FIT XR
- 미드시청
- leetcode
- Problem Solving
- 쓰릴오브파이트
- 괜찮음
- 운동
- 프로젝트
- 10분
- Daily Challenge
- realclass
- 개발자
- 링피트
- 매일
- 사이드
- 화상영어
- 3줄정리
- 만화도
- English
- 파비최
- 리얼 클래스
- 월간
- 30분
- 읽기
- Writing
- 스탭퍼
- 뭐든
- 영어공부
- Today
- Total
파비의 매일매일 공부기록
Two Scoops of Django - #6장 본문
이번장은 장고에서 모델 이용하기에 대한 내용이다.
모델은 장고 프로젝트의 토대가 되는 부분으로 깊게 고려하지 않고 성급하게 작성하다 보면 낭패를 겪을 수 있다.
종종 급한 마음에 결과를 생각하지 않고 부주의하게 모델을 변경하거나 추가하기도 하는데
그러다 보면 임시방편으로 내린 결정으로 인한 나비효과로 더 괴로워지는 경우가 생길 수 있다.
그러므로 새 모델을 추가하거나 기존 모델 수정 시 깊게 생각해야 하며 탄탄하고 안전하게 토대를 다지는 방향으로 디자인해야 한다.
1. 모델이 너무 많으면 앱을 나눈다 : 앱 하나에 모델이 스무 개 이상 있다면 작은 앱으로 분리하는 걸 고려하라. 각 앱이 가진 모델수가 다섯 개를 넘지 않아야 함.
2. 모델 상속에 주의하라 : 멀티 테이블 상속을 피할 것. 모델들 사이에서 좀 더 명확한 OneToOneFields와 ForeignKeys를 이용하여 Join이 난립할 때도 좀 더 수월하게 컨트롤 가능
추상화 기초 클래스를 만드는 방법 :
class Meta:
abstract = True
접합 기반 상속은 심각한 성능 문제를 일으킬 소지가 있으며, 더욱이 여러 번 서브클래스 화해서 이용하면 문제가 될 소지가 더 커진다 => 접합 기반 상속의 예를 아직 못 봐서 어떤 내용인지 모르겠음. 아니면 이미 쓰고 있는데 인지를 못하는 걸지도..?
3. 마이그레이션에 대해 : 생각보다 마이그레이션 관련 이슈가 실무에서는 많이 일어난다. 마이그레이션 생성 팁은 다음과 같다.
- 새로운 앱이나 모델이 생성되면 새 모델에 대해 django.db.migrations를 실행. python manage.py makemigrations
- 생성된 마이그레이션 코드를 실행 전 생성된 코드를 살펴볼 것. 특히 복잡한 변경 사항이 적용된 경우 더 꼼꼼히 살펴볼 것. sqlmigrate 명령을 통해 어떤 SQL문이 실행되는지도 확인할 것
- 외부 앱에 대해 마이그레이션 처리 시 MIGRATION_MODUELS 세팅 활용
- 생성되는 마이그레이션 개수에 연연하지 말 것. 너무 많아서 불편할 경우 squashmigrations를 이용할 것.
- 배포 전 마이그레이션을 롤백할 수 있는지 확인 필요.
- 테이블에 이미 수백만 개의 데이터가 존재한다면 스테이징 서버 등에서 비슷한 크기의 데이터로 충분히 테스트해야 함. 운영 서버의 경우 마이그레이션이 더 오래 걸릴 수 있음
- MySQL 사용 시 : 스키마 변환 전 데이터베이스 반드시 백업할 것. MySQL은 스키마 변경에 대한 트랜젝션 지원하지 않음. 가능하면 DB 변환 전 읽기 전용 모드로 변경할 것. 큰 테이블의 경우 스키마 변경에 상당한 시간(ex: 수 시간)이 걸릴 수 있으므로 유의할 것.
나도 실무를 하다 보면 모델을 어떻게 디자인하는 게 좋을지 고민하게 되는데(아직은 모델 설계 까지는 안 하지만)
저자도 가장 어려운 주제 중 하나가 좋은 장고 모델을 디자인하는 방법이라고 한다. 여러 가지 전략을 다음에 소개한다.
1. 정규화하기 : 미숙하게 비 정규화하는 것을 최대한 피할 것. 데이터의 형태와 틀에 대한 지각이 필요
2. 캐시 활용 : 적절한 위치에서 캐시를 세팅하면 모델을 비정규화 할 때 발생하는 문제들을 상당수 해결할 수 있음
3. 반드시 필요한 경우에만 비정규화 : 비정규화가 만병통치약이 처럼 보일 수 있지만 실제로는 프로젝트를 복잡하게 만들고 데이터 손실의 위험을 증가시킬 수 있음.
4. 언제 null을 사용하고 언제 blank를 사용할지 결정 : 모델 정의 시 null=True, blank=True 설정 옵션 선택 가능.(디폴트로는 모두 False) 책에 자세한 가이드라인을 소개함.
5. 언제 BinaryField를 이용할지 결정 : 웬만하면 안 쓰는 게 좋을 듯. 정 필요하다면 FileField에 레퍼런스만 저장하는 방식 활용. 파일을 직접 해당 필드를 통해 서비스하는 건 지양할 것.
6. 범용 관계 피하기 : 한 테이블로부터 다른 테이블을 서로 제약 조건이 없는 외부 키로 바인딩하는 범용 관계를 피할 것. 쿼리 속도 느려질 수 있으며 데이터 충돌의 위험성 존재
7. PostgreSQL 사용 시 언제 null, 언제 blank 사용할지 결정 : 책에 자세한 가이드 제공.
모델의 _meta API : 지금까지는 따로 이런 걸 사용해본 적은 없지만 만약 필요한 경우는 다음과 같은 이유일 수 있다고 한다.
- 모델 필드의 리스트를 가져올 때
- 모델의 특정 필드의 클래스를 가져올 때(or 상속 관계나 상속 등을 통해 생성된 정보를 가져올 때)
- 앞으로의 장고 버전들에서 이러한 정보를 어떻게 가져오게 되었는지 확실하게 상수로 남기기를 원할 때
- 장고 모델의 자체 검사 도구로 사용되는 상황
- 라이브러리를 이용해서 특별하게 커스터마이징 된 자신만의 장고를 만들려는 상황
- 장고의 모델 데이터를 조정하거나 변경할 수 있는 관리 도구를 제작하려는 상황
- 시각화나 분석 라이브러리를 제작하려는 상황
모델 매니저 : 모델에 질의를 하게 되면 장고의 ORM을 통하게 되는데, 이때 우리는 모델 매니저라는 데이터베이스와 연동하는 인터페이스를 호출한다. 모델 매니저는 원하는 클래스들을 제어하기 위해 모델 클래서의 모든 인스턴스 세트에 작동하게 됨. 장고는 각 모델 클래스에 대한 기본 모델 매니저를 제공하며 따로 제작할 수도 있음.
마지막으로 거대 모델 이해하기에 대한 내용이다.
거대 모델(fat model) : 데이터 관련 코드를 뷰나 템플릿에 넣지 않고 모델 메서드, 클래스 메서드, 프로퍼티 혹은 매니저 메서드 안에 넣어 캡슐화한 모델.
거대 모델을 사용하면 코드 재사용을 개선할 수 있는 최고의 방법일 수 있지만, 모델 코드 크기를 '신의 객체(god object) 수준으로 증가시키므로 모델 클래스 자체가 수천-수만 줄이 될 수 있어 테스트 및 유지보수가 용이하지 않다. 그러므로 여러 작은 크기로 분리하는 방향으로 선회하는 게 좋은데 모델 행동(model behavior)이나 헬퍼 함수(stateless helper function)로 이전할 수 있다.
1. 모델 행동(Mixin) : mixin을 실무에서 꽤 많이 봐왔는데 이런 이유로 쓰는지는 몰랐다. 근데 생각보다 디버깅할 때 불편한데.. 같은 파일이 아니다 보니 왔다 갔다 하면서 헷갈리는 경우가 발생하긴 한다. 여하튼 저자는 믹스인 활용을 추천한다.
2. 상태 없는 헬퍼 함수 : 모델로부터 로직을 띄어 유틸리티 함수로 넣어 좀 더 독립적인 구성이 가능. 로직에 대한 테스트가 좀 더 용이해지나 해당 함수들이 자신의 stateless함수에 더 많은 인자를 필요로 할 수 있다.
마지막으로 저자는 정규화 이후 비정규화를 수행할 것을 추천하며
raw SQL이나 적절한 캐시, 인덱스 등을 활용하여 성능 문제 해결을 추천한다.
만약 모델 간 상속을 이용하려고 한다면 접합 모델(concreate model)이 아니라 추상화 기초 클래스로부터 상속할 것을 추천한다.
django-model-utils와 django-extensions를 유용하게 쓸 것을 추천(실무에서는 쓰는 중)
다음장에서는 쿼리와 데이터베이스 레이어에 대해 다룰 예정이라고 한다.
'Study > Python' 카테고리의 다른 글
Two Scoops of Django - #8장 (0) | 2021.06.09 |
---|---|
Two Scoops of Django - #7장 (0) | 2021.06.08 |
Two Scoops of Django - #5장 (0) | 2021.06.06 |
Two Scoops of Django - #4장 (0) | 2021.06.05 |
Two Scoops of Django - #3장 (0) | 2021.06.04 |