Pylons:与外部库共享SQLAlchemy MySQL连接

1 投票
2 回答
944 浏览
提问于 2025-04-16 06:15

我正在使用Pylons和SQLAlchemy来连接MySQL,所以当我想在控制器中使用数据库连接时,可以这样做:

from myapp.model.meta import Session

class SomeController(BaseController):
    def index(self):
        conn = Session.connection()
        rows = conn.execute('SELECT whatever')
...

假设我的控制器需要调用一个外部库,这个库也需要数据库连接,我想把已经建立的SQLAlchemy MySQL连接提供给它:

from myapp.model.meta import Session

import mymodule

class SomeController(BaseController):
    def index(self):
        conn = Session.connection()
        myobject = mymodule.someobject(DATABASE_OBJECT)
        ...
        conn.close()

那么,DATABSE_OBJECT应该是什么呢?可能的选项有:

  1. 传递Session,然后在模块代码中打开和关闭Session.connection()
  2. 传递conn,然后在控制器中调用conn.close()
  3. 只传递连接参数,让模块代码自己建立连接

还有一个问题是,我需要在app_globals.py中实例化一些对象,这些对象也需要数据库连接。看起来app_globals.py还不能使用Session的SQLAlchemy连接——它还没有绑定。

我的架构根本上有问题吗?我这样在Pylons和外部库之间共享连接是否不妥呢?谢谢!

2 个回答

1
数据库对象应该是什么呢?可能的选择:

4. 传递一个“代理”或“助手”对象,这个对象有更高层次的抽象接口。

除非外部库真的需要直接访问SQLAlchemy的会话,否则你可以提供一个有类似“get_account(account_no)”这样的方法的对象,而不是“execute(sql)”。这样做可以让SQLAlchemy相关的代码更加独立,同时代码也更容易测试。

抱歉这不是对你原问题的直接回答,更像是一个设计建议。

2

你不需要自己去管理连接,这些都是由SQLAlchemy来处理的。只要在任何地方使用scoped session对象就可以了,这样就没问题。

def init_model(engine):
    sm = orm.sessionmaker(autoflush=False, autocommit=False, expire_on_commit=False, bind=engine)
    meta.engine = engine
    meta.Session = orm.scoped_session(sm)

def index(self):
    rows = Session.execute('SELECT ...')

你可以把Session对象传给你的外部库,然后在那儿随意进行查询。你不需要去调用.close()这个方法。

关于app_globals的问题,我是通过在globals类中添加了一个方法来解决的,这个方法是在从environment.py初始化数据库之后调用的。

class Globals(...):
    def init_model(self, config):
        self.some_persistent_db_object = Session.execute('...')

def load_environment(...):
    ...
    config['pylons.app_globals'].init_model(config)
    return config

撰写回答