如何将相关的 SQLAlchemy 映射类分布到不同模块的问题已经出现 quite一个few次here .不过,没有一个提议的解决方案对我很有效,我很想知道如何正确处理(即我不想让我的代码可运行,我想做正确的事)。
我很喜欢this solution :
基础.py from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
a.py 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
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")
b.py 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 B(Base):
__tablename__ = "B"
id = Column(Integer, primary_key=True)
A_id = Column(Integer, ForeignKey("A.id"))
c.py 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 *
from base import Base
class C(Base):
__tablename__ = "C"
id = Column(Integer, primary_key=True)
A_id = Column(Integer, ForeignKey("A.id"))
主.py 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
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 类做一些事情,而不是定义它怎么办?例如
a.py 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)
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 -> main -> a import。
所以我通常会在某处定义 A (a.py),然后在导入 main (a_functions.py ?) 的单独模块中执行操作。或者,由于创建 session 不需要导入映射类但创建表需要,我是否将这两个功能放在不同的模块中?或者我在 main.py 中做了一些粗暴的事情,比如
def create_tables():
import a, b, c
engine = create_engine("sqlite:///:memory:")
base.metadata.create_all(engine)
这样 a、b 和 c 仅在我需要创建表时有条件地导入,避免循环导入?
简而言之,使用 SQLAlchemy 的包的惯用高级组织是什么样的?
请您参考如下方法:
我认为这实际上是 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__' block 。
