ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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에 마이그레이션을 할때 순차적으로 진행되어 오류가 발생하지 않는다.

Designed by Tistory.