sql >> Base de Datos >  >> RDS >> Mysql

Manejar el reinicio de mysql en SQLAlchemy

Nota 2021: La respuesta original es de 2010. Ahora, el mejor enfoque, como se señala en los comentarios, parece ser usar parámetro pool_recycle .

La respuesta original de 2010 sigue.

Ver EDIT en la parte inferior para la solución probada

No lo probé, pero tal vez usando PoolListener es un camino a seguir?

Podrías hacer algo como esto:

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 esta manera, cada vez que la conexión está a punto de ser verificada desde el grupo, probamos si realmente está conectado al servidor. Si no, le damos a sqlalchemy una oportunidad para volver a conectarse. Después de eso, si el problema persiste, lo dejamos pasar.

PD:No probé si esto funciona.

Editar:en cuanto a los Pylons, las modificaciones a la inicialización del motor que se muestran arriba deberían realizarse en your_app.model.init_model (Pylons 0.9.7) o your_app.config.environment.load_environment (Torres 1.0) función - estos son estos son los lugares lugar donde se crea la instancia del motor.

EDITAR

Está bien. Pude reproducir la situación descrita. El código anterior necesita algunos cambios para funcionar. A continuación se muestra cómo debe hacerse. Además, no importa si es 0.9.7 o 1.0.

Debe editar your_app/config/environment.py. Ponga estas exportaciones en la parte superior del archivo:

import sqlalchemy
import sqlalchemy.interfaces
import _mysql_exceptions

Y el final de la función load_environment debería verse así:

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)

Esta vez pude probarlo (en Pylons 1.0 + SQLAlchemy 0.6.1) y funciona. :)