일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- bulk_create
- Spring
- 컨트리뷰팅
- API문서화
- circuitbreaker
- DI
- 함수형프로그래밍
- Not Null constraint failed
- SpringBoot
- 운영체제
- Java
- IOC
- resilience4j
- 상속모델
- cannot import name
- 쿼리셋합치기
- 프로젝트설정
- django
- 주니어개발자
- 객체비교
- 토이프로젝트
- 좋은코드란
- 마이크로서비스패턴
- bean-validator
- 2차원배열 정렬
- n poem
- 일급함수
- GraphQL
- Npoem
- circular dependency
- Today
- Total
코딩 하는 가든
Django - circular dependency 문제 (feat. cannot import name 'model') 본문
Circular Dependency
circular dependency는 순수 해석 그대로 circular(순환) dependency(의존성) 때문에 생기는 문제이다.
그럼 의존성이란 무엇인가?
예를 들어 A.py 라는 소스가 필요에 의해 B.py의 소스를 import 해 왔다고 치자 그렇다면 A 는 B에 의존성이 걸려 버린 것이다. 간단히 나타내면 A - > B 처럼 볼 수도 있겠다. 이어서 B.py는 C.py를 import 할 수 있다. 이처럼 A -> B -> C - > D -> ...
이런 식으로 각 소스간의 의존성을 나타 낼 수 있는데 이렇게 주욱 늘어지다가 dependency가 최초에 dependency를 건 A로 되돌아 오면 다음과 같은 그림이 완성 된다.
Django는 실행시 파이썬 코드를 한줄 한줄 읽어가며 필요한 소스를 import 해온다. A라는 파일에서 import B를 만나면 B로 가서 소스를 읽고, import C를 만나면 C로 가서 소스를 읽는 형식이다. 이럴 때, 위와 같은 A - > B -> C - > D - > A 같은 의존성이 생겨버리면 Django는 파일 import 를 무한히 반복하게 되어 결국 ImportError: cannot import name '~~~' 같은 에러를 낼 것이다.
Django에서의 간단한 예시를 통해 알아보자. Django 에서는 이러한 circular dependency가 모델간의 foriengkey 관계에서 자주 일어나는데
from django.db import models
from professor import Professor
class Student(models.Model):
professor = models.Foreingkey(Professor, on_delete=models.CASCADE, help_text="담당교수")
~~~
~~~
from django.db import models
from student import Student
class Professor(models.Model):
student = models.Foreingkey(Student, on_delete=models.CASCADE, help_text="담당학생")
~~~
~~~
위의 두 모델은 서로를 import 해오려고 하기 때문에 에러를 낼 것이다.
이를 해결 하려면 다음과 같이 Foreingkey 필드의 모델 부분에 'app_name.Model_name'을 적어주면 해당 model을 runtime에 필요시에 임포트 해 오기 때문에 오류를 띄우지 않을 것이다,
from django.db import models
class Student(models.Model):
professor = models.Foreingkey('professor.Professor', on_delete=models.CASCADE, help_text="담당교수")
~~~
~~~
from django.db import models
class Professor(models.Model):
student = models.Foreingkey('student.Student', on_delete=models.CASCADE, help_text="담당학생")
~~~
~~~
그렇기 때문에 Foreingkey를 사용할 때에는 'app.Model'로 임포트 해오는 것을 습관화 하자. 당장에는 문제가 발생하지 않더라도 프로젝트의 규모가 커지고 앱이 많아지다보면 언제 어디에서 circular dependency가 발생할지 모른다.
'Django' 카테고리의 다른 글
Django - bulk_create와 사용시 주의할 점 (1) | 2020.04.01 |
---|---|
Django - Queryset 합치기와 주의점 ('|' 연산자, union의 차이점) (0) | 2020.03.18 |
Django - PostgreSQL과 상속 모델의 Sequence (feat. Not Null constraint failed id) (1) | 2020.03.18 |