问题
I'm creating a webapp which uses SQLAlchemy to access the database. I'm getting stuck with two models which are referencing to each other and ending up in an circular import which throws the following exception:
--- SNIPP --- (output modified to hide software name)
File "/opt/promethium/service/opt/xxxx/lib/python/api/server/server.py", line 11, in <module>
from api.server.controllers import *
File "/opt/promethium/service/opt/xxxx/lib/python/api/server/controllers/__init__.py", line 3, in <module>
from messagescontroller import MessagesController
File "/opt/promethium/service/opt/xxxx/lib/python/api/server/controllers/messagescontroller.py", line 7, in <module>
from api.server.models import MessageModel, EmailModel, KeyModel, MessagerecipientModel
File "/opt/promethium/service/opt/xxxx/lib/python/api/server/models/__init__.py", line 6, in <module>
from keymodel import KeyModel
File "/opt/promethium/service/opt/xxxx/lib/python/api/server/models/keymodel.py", line 18, in <module>
from api.server.models import ApplicationModel, EmailModel
ImportError: cannot import name EmailModel
These are the files and their code:
__init__.py
from applicationmodel import ApplicationModel
# some other imports here
from emailmodel import EmailModel
from keymodel import KeyModel
# some more imports here
keymodel.py
from sqlalchemy import Column, Integer, String, Date
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, backref, deferred
from sqlalchemy.ext.declarative import _declarative_constructor
from sqlalchemy import event
from pyncacoreapi.server.models import ApplicationModel, EmailModel
from pyncacoreapi.server.libs.store import Base
class KeyModel(ApplicationModel, Base):
__tablename__ = "keys"
id = Column(Integer, primary_key=True)
email_id = Column(Integer, ForeignKey("emails.id"))
email = relationship("EmailModel", uselist=False, backref=backref("keys"))
symmetrickey = deferred(Column(String,unique=True))
certificate = deferred(Column(String,unique=True))
privatekey = deferred(Column(String,unique=True))
publickey = deferred(Column(String,unique=True))
keymaterial = Column(String,unique=False)
emailmodel.py
from sqlalchemy import Column, Integer, String, Date
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.ext.declarative import _declarative_constructor
from pyncacoreapi.server.models import ApplicationModel, KeyModel, DomainModel
from pyncacoreapi.server.libs.store import Base, Db
from sqlalchemy import event
class EmailModel(ApplicationModel, Base):
__tablename__ = "emails"
id = Column(Integer, primary_key=True)
email = Column(String, unique=True)
domain_id = Column(Integer, ForeignKey("domains.id"))
domain = relationship("DomainModel",backref=backref("emails", order_by=id))
account_id = Column(Integer, ForeignKey("accounts.id"))
account = relationship("AccountModel",backref=backref("emails", order_by=id))
What do i have to do to get this import stuff correct? Whats the best practice or the "golden rule" for that? Thanks for any help!!!!
回答1:
In this specific case, there is no need to import EmailModel
at all. Alter keymodel.py
to remove the import:
from pyncacoreapi.server.models import ApplicationModel
SQLAlchemy postpones resolving references given as strings until the last possible moment anyway, so it doesn't matter here that EmailModel
is defined yet or not. You are referring to it in the email
relationship via a string.
来源:https://stackoverflow.com/questions/15547156/circular-dependency-in-models-with-sqlalchemy