Mysql
 sql >> Base de données >  >> RDS >> Mysql

Gérer le redémarrage de mysql dans SQLAlchemy

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. :)