Jhorra
Jhorra

Reputation: 6321

Python recursive import issue

I have a Python/Flask app that uses MongoEngine for the database. I have defined my models, and everything was working until the newest models were added. I believe the problem occurs because both models reference each other and it's causing a recursive import loop. I'm not sure what to do to solve it though. This is going to be a large project with lots of models referencing each other. This particular instance is because users are in practices, and practices have users, so it's a many to many relationship.

User Model

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))

And the practice model

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))

The error I get is ImportError: cannot import name 'Practice'

I have two other models that are running into the same issue. The models worked fine until I added in the imports to the other model.

Upvotes: 0

Views: 331

Answers (2)

Robert Wisner
Robert Wisner

Reputation: 155

I am by no means an expert on MongoEngine, but it looks like you can reference a model by string as opposed to by class. In that case you can change your Practice model to look like this.

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'))

I hope this helps.

Upvotes: 2

Prune
Prune

Reputation: 77837

The short answer is that you can't have circular references. The compiler doesn't trust that you will properly "bottom out" on resolving references, and it's not going to iterate through the graph to find out.

One way to fix this is to use a master class that imports the various classes; your worker classes then import their needs from the master class.

Upvotes: 2

Related Questions