Python 如何将SQLAlchemy声明性模型拆分为模块?
我需要定义多个包含SQLAlchemy声明类的模块。我在每个模块中都编写了一个名为Python 如何将SQLAlchemy声明性模型拆分为模块?,python,sqlalchemy,Python,Sqlalchemy,我需要定义多个包含SQLAlchemy声明类的模块。我在每个模块中都编写了一个名为subclass_base()的函数,实例化后将声明性_base()的基本实例传递到该函数中。第一个模块的子类\u base()调用正确地将基本实例子类化,并且子类从函数外部可见。第二个模块的调用在没有错误的情况下完成,但是从函数内部和外部来看,所有子类都反映在Base中。下面是一个最小的工作示例,每个模块中只有一个类定义: 模型a.py from sqlalchemy import Column, Integer
subclass_base()
的函数,实例化后将声明性_base()
的基本实例传递到该函数中。第一个模块的子类\u base()
调用正确地将基本实例子类化,并且子类从函数外部可见。第二个模块的调用在没有错误的情况下完成,但是从函数内部和外部来看,所有子类都反映在Base中。下面是一个最小的工作示例,每个模块中只有一个类定义:
模型a.py
from sqlalchemy import Column, Integer, String
def subclass_base(Base):
class Roles(Base):
__tablename__ = 'roles'
id = Column(Integer, primary_key=True)
name = Column(String(32))
from sqlalchemy import Column, Integer, String
from db import Base
class Roles(Base):
__tablename__ = 'roles'
id = Column(Integer, primary_key=True)
name = Column(String(32))
模型b.py
from sqlalchemy import Column, Integer, String
def subclass_base(Base):
class Locations(Base):
__tablename__ = 'locations'
id = Column(Integer, primary_key=True)
name = Column(String(64))
from sqlalchemy import Column, Integer, String
from db import Base
class Locations(Base):
__tablename__ = 'locations'
id = Column(Integer, primary_key=True)
name = Column(String(64))
test.py
from sqlalchemy.ext.declarative import declarative_base
from modela import subclass_base as amod
from modelb import subclass_base as bmod
def test():
count = 0
while True:
try:
Base = declarative_base()
amod(Base)
bmod(Base)
sc = [subclass.__name__ for subclass in Base.__subclasses__()]
assert(len(sc) == 2)
print('.', end='')
count += 1
except AssertionError:
print("Failed after {} successful pass(es)".format(count))
count = 0
我怀疑这个问题是因为我忽略了元类工作的一个特定问题,而元类工作是在声明性的_base()上进行的,但我似乎不知道发生了什么。我还想知道这是否是一个继承问题。是否有一种不同的体系结构方法,我应该采用,而不是使用函数来对单个基类进行子类化?不要在函数中定义类。只需在单个定义模块中定义Base
,然后从其他模块导入该模块:
db.py
模型a.py
from sqlalchemy import Column, Integer, String
def subclass_base(Base):
class Roles(Base):
__tablename__ = 'roles'
id = Column(Integer, primary_key=True)
name = Column(String(32))
from sqlalchemy import Column, Integer, String
from db import Base
class Roles(Base):
__tablename__ = 'roles'
id = Column(Integer, primary_key=True)
name = Column(String(32))
模型b.py
from sqlalchemy import Column, Integer, String
def subclass_base(Base):
class Locations(Base):
__tablename__ = 'locations'
id = Column(Integer, primary_key=True)
name = Column(String(64))
from sqlalchemy import Column, Integer, String
from db import Base
class Locations(Base):
__tablename__ = 'locations'
id = Column(Integer, primary_key=True)
name = Column(String(64))
user_script.py
from sqlalchemy import create_engine
engine = create_engine('postgresql://user:pwd@server/database')
from yourproject.db import bind_engine
bind_engine(engine)
这并不能解决我的特殊问题:其中一个模块打算通过pip打包分发,因此一旦安装,终端用户就不需要编辑模块。因为最终用户实例化了他们自己的基,所以我需要以某种方式将其传递给模块。即使我强迫用户使用模块的基座,也会阻止第二个模块使用基座。我们的目标是将应用程序模块化为有用的组件,这些组件在共享数据库中有专用的表。您为什么要使用用户的库
?你不应该。如果用户需要,他们可以创建自己的库
@DeanStamlerSo这很有趣。多个基地可以共享一个数据库?他们是否也共享一个会话或引擎?也许这就是解决方案。@Deanstaller用户可以提供他们的引擎供您绑定到您的基础上。我编辑了答案以显示这一点:@deanstaller关于共享会话,这取决于用例,如果您的用户需要,他们可以使用您的sessionmaker,或者他们可以为自己的目的创建自己的会话