Remarque 2021 : La réponse originale date de 2010. Maintenant, la meilleure approche, comme indiqué dans les commentaires, semble être en utilisant paramètre pool_recycle .
La réponse originale de 2010 suit.
Voir EDIT en bas pour la solution testée
Je ne l'ai pas essayé, mais peut-être en utilisant PoolListener est une voie à suivre ?
Vous pourriez faire quelque chose comme ceci :
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()])
De cette façon, chaque fois que la connexion est sur le point d'être extraite du pool, nous testons si elle est réellement connectée au serveur. Sinon, nous donnons à sqlalchemy une chance de se reconnecter. Après cela, si le problème persiste, nous le laissons tomber.
PS :je n'ai pas testé si cela fonctionne.
Edit :Comme pour les pylônes, les modifications de l'initialisation du moteur indiquées ci-dessus devraient être effectuées dans your_app.model.init_model (Pylons 0.9.7) ou your_app.config.environment.load_environment (Pylons 1.0) fonction - ce sont ce sont les endroits endroit où l'instance de moteur est créée.
MODIFIER
D'accord. J'ai pu reproduire la situation décrite. Le code ci-dessus a besoin de quelques modifications pour fonctionner. Vous trouverez ci-dessous comment procéder. De plus, peu importe qu'il s'agisse de la version 0.9.7 ou 1.0.
Vous devez modifier your_app/config/environment.py. Placez ces exportations en haut du fichier :
import sqlalchemy
import sqlalchemy.interfaces
import _mysql_exceptions
Et la fin de la fonction load_environment devrait ressembler à ça :
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)
Cette fois, j'ai pu le tester (sur Pylons 1.0 + SQLAlchemy 0.6.1) et ça marche. :)