如何将相关的SQLAlchemy映射类分布在不同模块中的问题出现quite一few次here。虽然提议的解决方案都不适合我,但我很想知道这是如何正确处理的(即我不想让我的代码可以运行,我想这样做)。
我非常喜欢this solution:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from sqlalchemy import *
from base import Base
from sqlalchemy.orm import relationship
class A(Base):
__tablename__ = "A"
id = Column(Integer, primary_key=True)
Bs = relationship("B", backref="A.id")
Cs = relationship("C", backref="A.id")
from sqlalchemy import *
from base import Base
class B(Base):
__tablename__ = "B"
id = Column(Integer, primary_key=True)
A_id = Column(Integer, ForeignKey("A.id"))
from sqlalchemy import *
from base import Base
class C(Base):
__tablename__ = "C"
id = Column(Integer, primary_key=True)
A_id = Column(Integer, ForeignKey("A.id"))
from sqlalchemy import create_engine
from sqlalchemy.orm import relationship, backref, sessionmaker
import base
import a
import b
import c
engine = create_engine("sqlite:///:memory:")
base.Base.metadata.create_all(engine, checkfirst=True)
Session = sessionmaker(bind=engine)
session = Session()
# snip
但是,如果我想在a.py中使用A类做东西,除了定义它之外怎么办? e.g。
from sqlalchemy import *
from base import Base
from sqlalchemy.orm import relationship
import main
class A(Base):
__tablename__ = "A"
id = Column(Integer, primary_key=True)
Bs = relationship("B", backref="A.id")
Cs = relationship("C", backref="A.id")
def populate_A(session):
for i in range(10):
new_A = A(id=i)
session.add(new_A)
session.commit()
if __name__ == '__main__':
session = main.Session()
populate_A(session)
这就是我想要构建代码的方式 - 从语义上讲,A和populate_A似乎应该存在于同一个模块中。但显然这在上面的例子中不起作用,因为圆形a - >主要 - >进口。
所以我通常会定义A somewhere(a.py),然后在导入main(a_functions.py?)的单独模块中执行操作。或者,由于创建会话不需要导入映射类但是创建表,我是否将这两个功能放在不同的模块中?或者我在main.py中做一些粗略的事情,比如
def create_tables():
import a, b, c
engine = create_engine("sqlite:///:memory:")
base.metadata.create_all(engine)
所以当我需要创建表时,a,b和c只是有条件地导入,避免循环导入?
简而言之,使用SQLAlchemy的包的惯用高级组织是什么样的?
答案 0 :(得分:0)
我认为这实际上是Python习语的问题,而不是SQLAlchemy习语。 According to Guido Van Rossum, running scripts within a package is an anti-pattern(zzeek在评论中暗示了这一点)。所以a.py,b.py和c.py不应该有if __name__ == '__main__'
块。