2021注: 元の回答は2010年のものです。コメントで指摘されているように、より良いアプローチはを使用することです。 pool_recycle param 。
2010年の元の回答は次のとおりです。
テスト済みのソリューションについては、下部の編集を参照してください
試していませんが、おそらく 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()])
このようにして、接続がプールからチェックアウトされるたびに、実際にサーバーに接続されているかどうかをテストします。そうでない場合は、sqlalchemyに再接続する機会を1回与えます。その後、問題が解決しない場合は、問題を解決します。
PS:これが機能するかどうかはテストしていません。
編集:パイロンに関しては、上記のエンジン初期化の変更は、 your_app.model.init_model(Pylons 0.9.7)またはで行う必要があります。 your_app.config.environment.load_environment (Pylons 1.0) 関数-これらは これは場所です エンジンインスタンスが作成される場所。
編集
わかりました。説明した状況を再現することができました。上記のコードを機能させるには、いくつかの変更が必要です。以下はそれがどのように行われるべきかです。また、0.9.7でも1.0でも構いません。
your_app / config/environment.pyを編集する必要があります。これらのエクスポートをファイルの先頭に配置します:
import sqlalchemy
import sqlalchemy.interfaces
import _mysql_exceptions
そして、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)
今回はそれをテストすることができ(Pylons 1.0 + SQLAlchemy 0.6.1で)、動作します。 :)