-
Django migration 순환참조 오류 해결방법Web/Django 2022. 5. 15. 22:57
django를 사용한 프로젝트에서 모델링을 할 때 다대다 테이블을 정의하거나, 여러 앱간에 관계를 가진 테이블을 만들고 makemigration이나 migrate를 할 때 의존성 문제가 생기는 경우가 있다. 다음과 같은 models 파일이 있다고 치자.
#products/models.py class Product(models.Model): name = models.CharField(max_length=45) price = models.DecimalField(max_digits=10, decimal_places=2) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)
#users/models.py from products.models import Product class User name = models.CharField(max_length=45) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) orders = models.ManyToManyField(Product, through="orders.Order", related_name='user_order'
#orders/models.py from products.models import Product from users.models import User class Order(models): user = models.Foreignkey(User, on_delete=models.CASCADE) product = models.Foreignkey(Product, on_delete=models.CASCADE)
이렇게 models을 작성한후 makemigrations을 하면 순환참조 오류가 발생한다.
#users/models.py class User name = models.CharField(max_length=45) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) orders = models.ManyToManyField('products.Product', through="orders.Order", related_name='user_order'
#orders/models.py class Order(models): user = models.Foreignkey('users.User', on_delete=models.CASCADE) product = models.Foreignkey('products.Product', on_delete=models.CASCADE)
위와 같이 속성에 참조할 model을 직접적으로 import해서 쓰는 것이 아닌, 따옴표를 이용해 표시하면 순환 참조 오류를 해결할 수 있다.
첫번째 해결방법으로도 오류를 풀 수 없는 경우가 있다. 그럴때는 역참조 테이블에서 m2m 테이블을 선언한 부분을 주석처리하고 마이그레이션 파일을 만든후 , 주석을 푼후 다시 마이그레이션 파일을 만들면 된다. m2m 테이블 모델은 주석 처리 할 필요가 없고, 만약 같은 테이블들을 참조하는 m2m 테이블이 여러개 있다면 하나씩 주석을 풀고 마이그레이션 파일을 만들어야 한다.
#users/models.py class User name = models.CharField(max_length=45) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) #아래와 같이 M2M 필드를 선언한 부분을 주석처리하고 첫번째 마이그레이션 파일을 생성 해야한다. #orders = models.ManyToManyField('products.Product', through="orders.Order", related_name='user_order'
이렇게 하면 app의 migrations 폴더에 두개 이상의 마이그레이션 파일이 생기게 되는데, 각각의 순서가 정해져 있어서 최종적으로 db에 마이그레이션을 할때 순차적으로 진행되어 오류가 발생하지 않는다.
'Web > Django' 카테고리의 다른 글
django가 제공해주는 회원가입/로그인 기능 (0) 2022.05.26 유닛 테스트중 You can't execute queries until the end of the 'atomic' block 해결 방법 (0) 2022.05.25 ManyToManyField 사용의 장점 (0) 2022.04.13