2016-12-20 90 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