2016-12-20 7 views
0

데이터베이스에 MongoEngine을 사용하는 Python/Flask 앱이 있습니다. 내 모델을 정의했고, 최신 모델이 추가 될 때까지 모든 것이 작동했습니다. 나는 두 모델이 서로를 참조하고 재귀 수입 루프를 일으키기 때문에 문제가 발생한다고 생각한다. 나는 그것을 해결하기 위해 무엇을해야할지 모르겠다. 이것은 서로 참조하는 많은 모델을 가진 커다란 프로젝트가 될 것입니다. 이 특정 사례는 사용자가 관행에 있고 관행에 사용자가 있기 때문에 많은 관계가 있습니다.Python 재귀 가져 오기 문제

사용자 모델

from utilities.common import utc_now_ts as now 
from mongoengine import * 
from models.practice import Practice 

class User(Document): 
    name = StringField() 
    created = IntField(db_field="cr", default=now) 
    practices = ListField(ReferenceField(Practice)) 

그리고 연습 모델

from utilities.common import utc_now_ts as now 
from mongoengine import * 
from models import user 

class Practice(Document): 
    name = StringField() 
    created = IntField(db_field="cr", default=now) 
    users = ListField(ReferenceField(user.User)) 
    admins = ListField(ReferenceField(user.User)) 

내가 오류 내가 같은 문제로 실행하는 두 개의 다른 모델을 가지고 ImportError: cannot import name 'Practice'

입니다. 모델은 다른 모델로 가져 오기 작업을 추가 할 때까지 제대로 작동했습니다.

+0

재귀 적으로 참조되는 이유가 있습니까? 이 문제를 해결하는 가장 좋은 방법은 종속성 중 하나를 제거하는 모델 리팩터가 될 가능성이 큽니다. –

+0

변경 방법을 알려주시겠습니까? 각 모델에 대한 사용자 목록이 있어야하며 각 사용자에 대한 그룹 목록이 있어야합니다. 이것은 주제를 검색 할 때 사람들이 추천 한 방법이었습니다. – Jhorra

답변

2

나는 MongoEngine의 전문가는 아니지만 클래스가 아닌 문자열로 모델을 참조 할 수있는 것처럼 보입니다. 이 경우 Practice 모델을 이렇게 변경할 수 있습니다.

from utilities.common import utc_now_ts as now 
from mongoengine import * 


class Practice(Document): 
    name = StringField() 
    created = IntField(db_field="cr", default=now) 
    users = ListField(ReferenceField('User')) 
    admins = ListField(ReferenceField('User')) 

이 정보가 도움이되기를 바랍니다.

2

짧은 대답은 순환 참조를 가질 수 없다는 것입니다. 컴파일러는 참조를 해결할 때 제대로 "밑바닥으로"나올 것이라고 신뢰하지 않으며, 그래프를 통해 반복을 찾아 낼 수도 없습니다.

이 문제를 해결하는 한 가지 방법은 다양한 클래스를 가져 오는 마스터 클래스를 사용하는 것입니다. 그런 다음 작업자 클래스는 마스터 클래스에서 필요를 가져옵니다.

+0

이 두 클래스 만 있다고 가정하면 마스터 클래스의 모습을 보여줄 수 있습니까? – Jhorra

+1

[여기] (http://stackoverflow.com/questions/1556387/circular-import-dependency-in-python) 토론을보십시오. – Prune