wRA*_*RAR 8 mysql error-handling pylons sqlalchemy
我的Pylons应用程序通过SQLAlchemy和python-MySQLdb使用本地MySQL服务器.当服务器重新启动时,打开的池连接显然已关闭,但应用程序不知道这一点,显然当它尝试使用这种连接时,它会收到"MySQL服务器已经消失":
File '/usr/lib/pymodules/python2.6/sqlalchemy/engine/default.py', line 277 in do_execute
cursor.execute(statement, parameters)
File '/usr/lib/pymodules/python2.6/MySQLdb/cursors.py', line 166 in execute
self.errorhandler(self, exc, value)
File '/usr/lib/pymodules/python2.6/MySQLdb/connections.py', line 35 in defaulterrorhandler
raise errorclass, errorvalue
OperationalError: (OperationalError) (2006, 'MySQL server has gone away')
Run Code Online (Sandbox Code Playgroud)
此异常不会被捕获到任何地方,因此它会冒泡到用户.如果我应该在我的代码中的某处处理此异常,请在Pylons WSGI应用程序中显示此类代码的位置.或者SA本身可能有解决方案吗?
请参阅底部的EDIT以获取测试解决方案
我没试过,但也许使用PoolListener是一种方法吗?
你可以这样做:
class MyListener(sqlalchemy.interfaces.PoolListener):
def __init__(self):
self.retried = False
def checkout(self, dbapi_con, con_record, con_proxy):
try:
dbapi_con.info() # is there any better way to simply check if connection to mysql is alive?
except sqlalchemy.exc.OperationalError:
if self.retried:
self.retried = False
raise # we do nothing
self.retried = True
raise sqlalchemy.exc.DisconnectionError
# next, code according to documentation linked above follows
e = create_engine("url://", listeners=[MyListener()])
Run Code Online (Sandbox Code Playgroud)
这样,每次从池中检出连接时,我们都会测试它是否实际连接到服务器.如果没有,我们给sqlalchemy一次机会重新连接.在那之后,如果问题仍然存在,我们放手.
PS:我没有测试这是否有效.
编辑:关于塔,修改发动机初始化上面显示将需要做your_app.model.init_model(塔0.9.7)或 your_app.config.environment.load_environment (塔1.0)功能- 这些都是这就是地方地方引擎实例被创建.
编辑
好.我能够重现描述的情况.上面的代码需要一些更改才能工作.以下是应该如何做的.无论是0.9.7还是1.0都没关系.
您需要编辑your_app/config/environment.py.将这些导出放在文件的顶部:
import sqlalchemy
import sqlalchemy.interfaces
import _mysql_exceptions
Run Code Online (Sandbox Code Playgroud)
load_environment函数的结尾应如下所示:
class MyListener(sqlalchemy.interfaces.PoolListener):
def __init__(self):
self.retried = False
def checkout(self, dbapi_con, con_record, con_proxy):
try:
dbapi_con.cursor().execute('select now()')
except _mysql_exceptions.OperationalError:
if self.retried:
self.retried = False
raise
self.retried = True
raise sqlalchemy.exc.DisconnectionError
config['sqlalchemy.listeners'] = [MyListener()]
engine = engine_from_config(config, 'sqlalchemy.')
init_model(engine)
Run Code Online (Sandbox Code Playgroud)
这次我能够测试它(在Pylons 1.0 + SQLAlchemy 0.6.1上)并且它可以工作.:)