如果想要使用SQLAlchemy将多个数据库连接到各种应用程序,那么组织模型、连接的好方法是什么?

2024-09-30 14:18:57 发布

您现在位置:Python中文网/ 问答频道 /正文

背景:

这就是我所面临的情况,到目前为止,我目前的解决方案似乎相当笨拙。我想改进一下。现在:

  • 我在金字塔应用程序的主要功能中设置与每个数据库的连接:
 def main(global_config, **settings):
    a_engine = engine_from_config(settings, 'A.')
    b_engine = engine_from_config(settings, 'B.')
    ASession.configure(bind=a_engine)
    BSession.configure(bind=b_engine)
  • “ASession”和“BSession”只是在/models/init.py中全局定义范围的\u session。在
ASession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
  • 我这样定义模型基类。例如:
ABase = declarative_base()
class user(ABase):
   id = Column(Integer, primary_key=True)
   name = Column(String)

不知怎么的,这已经感觉不太干净了。但是现在这个模型应该是从另一个应用程序访问的,我还需要在该应用程序中再次定义引擎和连接。这感觉非常多余。在

问题摘要:

假设有两个不同的数据库:

A和B

还假设您希望使用同一模型从两个不同的应用程序(例如:金字塔应用程序、使用Tornado的Bokeh服务器应用程序)访问A和B。在

简而言之,一个最好的模式对象/模型/类/函数如何在Python3中生成干净的非冗余代码?

问题发布后的初步想法:

再考虑一下这个问题,我想我希望每个模型都能“独立”。该模型应附带启动连接的方法。换句话说,数据库连接的启动应该与web应用程序本身分离。在

它应该以一种实例的方式来完成。以便多个应用程序可以使用相同的模型。每个应用程序都有自己的会话连接到其中一个数据库。在

社区会怎么做呢?星期五的下午至少不适合自己去寻找这些问题的答案。在


Tags: from模型config数据库应用程序settings定义bind
1条回答
网友
1楼 · 发布于 2024-09-30 14:18:57

我已经做到了。我下面的建议是我喜欢怎样做,但不是唯一的方法。我将抛弃作用域会话和事务管理器,并使用请求生命周期回调来处理会话的创建、关闭、提交或回滚,从而生成显式会话管理对象。基本上,作用域会话是一种通过为执行线程获取相同项来模拟全局的方法。在Pyramid中实现这一点的另一种方法是将东西附加到注册表和请求,因为这些东西无处不在。您可以将共享组件附加到注册表(ZCA),并将每个请求对象附加到请求。在

如果我发现有多个组件的话,我会很容易的把它们打包。对于您描述的这种情况,我制作了两个不同的DB引擎组件,它们是在启动时创建的,附加到注册表中,并且有一个获取新会话的方法。如果您正确地创建了这些组件,那么它们应该可以在任何应用程序中使用,无论是Pyramid、Tornado还是您的测试脚本。你只要确保它有一个构造函数,用某种合理的方式传入设置来设置引擎,不管是设置dict还是kwargs。然后,我让我的数据模型活在它们自己的python包中,很容易让家族中的任何应用程序导入模型,实例化引擎组件,然后进城。请注意,如果您喜欢使用ZCA注册表(我喜欢它,这是一个很棒的DI系统),那么没有什么可以阻止您在非金字塔应用程序中使用它,只需在服务器启动代码中手动设置即可。在

在Pyramid中,我创建一个定制的请求类,并使用具体化装饰器允许其他金字塔代码获取该请求的会话。request类有附加的终止回调来结束会话,并执行回滚或提交。这里有更多的样板,但对我来说,它更干净,因为我可以非常容易地跟踪我的会话管理发生在何时何地的代码和时间。这也是一个很好的测试方法。在

也就是说,在SQLAlchemy/Pyramid land中,有很多聪明人对作用域会话和事务管理器发誓,所以还有其他有效的方法。希望有帮助。在

相关问题 更多 >