Circular dependency in models with sqlalchemy

帅比萌擦擦* 提交于 2019-12-25 06:02:21

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!