Pylons:与外部库共享SQLAlchemy MySQL连接
我正在使用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应该是什么呢?可能的选项有:
- 传递
Session
,然后在模块代码中打开和关闭Session.connection()
- 传递
conn
,然后在控制器中调用conn.close()
- 只传递连接参数,让模块代码自己建立连接
还有一个问题是,我需要在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