Mysql
 sql >> Database >  >> RDS >> Mysql

Gestisci il riavvio di MySQL in SQLAlchemy

Nota 2021: La risposta originale è del 2010. Ora l'approccio migliore, come sottolineato nei commenti, sembra essere utilizzare parametro pool_recycle .

Segue la risposta originale del 2010.

Vedi EDIT in fondo per la soluzione testata

Non l'ho provato, ma forse usando PoolListener è una strada da percorrere?

Potresti fare qualcosa del genere:

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()])

In questo modo, ogni volta che la connessione sta per essere ritirata dal pool, testiamo se è effettivamente connessa al server. In caso contrario, diamo a sqlalchemy una possibilità di riconnettersi. Dopodiché, se il problema persiste, lo lasciamo andare.

PS:non ho testato se funziona.

Modifica:come per i Pylon, le modifiche all'inizializzazione del motore mostrate sopra dovrebbero essere eseguite in your_app.model.init_model (Pylons 0.9.7) o your_app.config.environment.load_environment (Pylon 1.0) funzione - questi sono questi sono i luoghi luogo in cui viene creata l'istanza del motore.

MODIFICA

Ok. Sono stato in grado di riprodurre la situazione descritta. Il codice sopra ha bisogno di alcune modifiche per funzionare. Di seguito è come dovrebbe essere fatto. Inoltre, non importa se è 0.9.7 o 1.0.

Devi modificare your_app/config/environment.py. Metti queste esportazioni in cima al file:

import sqlalchemy
import sqlalchemy.interfaces
import _mysql_exceptions

E la fine della funzione load_environment dovrebbe apparire così:

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)

Questa volta sono stato in grado di testarlo (su Pylons 1.0 + SQLAlchemy 0.6.1) e funziona. :)