2016-12-20 21 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)) 

私が手にエラーは、私は同じ問題に実行されている2つの他のモデルを持っているImportError: cannot import name 'Practice'

です。モデルは、他のモデルへのインポートで追加するまで正常に機能しました。

+0

再帰的に参照される理由はありますか?この問題を解決する最良の方法は、依存関係の1つを削除するためのモデルリファクタである可能性が最も高いです。 –

+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

簡単な答えは、循環参照を使用できないことです。コンパイラは、参照を解決する上で適切に「底を打つ」ことを信頼しません。また、グラフを繰り返して調べることもありません。

これを修正する方法の1つは、さまざまなクラスをインポートするマスタークラスを使用することです。ワーカークラスはマスタークラスからニーズをインポートします。

+0

これが私の唯一の2つのクラスであるとすれば、マスタークラスがどのように見えるかの例を教えてください。 – Jhorra

+1

ディスカッション[こちら](http://stackoverflow.com/questions/1556387/circular-import-dependency-in-python) – Prune