让我们看看下一个片段 -Python的SQLAlchemy的 - “MySQL服务器消失”
@event.listens_for(Pool, "checkout")
def check_connection(dbapi_con, con_record, con_proxy):
cursor = dbapi_con.cursor()
try:
cursor.execute("SELECT 1") # could also be dbapi_con.ping(),
# not sure what is better
except exc.OperationalError, ex:
if ex.args[0] in (2006, # MySQL server has gone away
2013, # Lost connection to MySQL server during query
2055): # Lost connection to MySQL server at '%s', system error: %d
# caught by pool, which will retry with a new connection
raise exc.DisconnectionError()
else:
raise
engine = create_engine('mysql://user:[email protected]/dbname', pool_recycle = 3600,pool_size=10, listeners=[check_connection])
session_factory = sessionmaker(bind = engine, autoflush=True, autocommit=False)
db_session = session_factory()
...
some code that may take several hours to run
...
db_session.execute('SELECT * FROM ' + P_TABLE + " WHERE id = '%s'" % id)
我认为结账事件下注册checkout_connection功能将解决它,但它现在didnt 的问题我是如何告诉SQLAlchemy处理连接丢失的,所以每次我调用execute()它都会检查连接是否可用,如果不是,它会再次启动它?
---- ---- UPDATE
的SQLAlchemy的版本是0.7.4
---- ---- UPDATE
def checkout_listener(dbapi_con, con_record, con_proxy):
try:
try:
dbapi_con.ping(False)
except TypeError:
dbapi_con.ping()
except dbapi_con.OperationalError as exc:
if exc.args[0] in (2006, 2013, 2014, 2045, 2055):
raise DisconnectionError()
else:
raise
engine = create_engine(CONNECTION_URI, pool_recycle = 3600,pool_size=10)
event.listen(engine, 'checkout', checkout_listener)
session_factory = sessionmaker(bind = engine, autoflush=True, autocommit=False)
db_session = session_factory()
session_factory发送到每个新创建的线程
class IncidentProcessor(threading.Thread):
def __init__(self, queue, session_factory):
if not isinstance(queue, Queue.Queue):
raise TypeError, "first argument should be of %s" (type(Queue.Queue))
self.queue = queue
self.db_session = scoped_session(session_factory)
threading.Thread.__init__(self)
def run(self):
self.db_session().execute('SELECT * FROM ...')
...
some code that takes alot of time
...
self.db_session().execute('SELECT * FROM ...')
现在当时间的大周期我得到的“MySQL服务器消失”错误
你检查是否被解雇结账事件?你是否也用@ event.listens_for(Pool,“checkout”)装饰你的函数check_connection?这个链接可能会有所帮助http://docs.sqlalchemy.org/en/latest/core/pooling.html#disconnect-handling-pessimistic –
哦,我忘了现在添加装饰,它似乎尝试使用该功能,但它会抛出一个异常说 - “没有实现任何:first_connect,checkin,checkout,connect” – Xeus
你正在使用什么版本的sqlalchemy?你也可以在这里发布修饰过的代码和装饰器吗? –