query multiple datatypes python mysql sqlalchemy flask database-connection

multiple - Evitar que "el servidor MySQL se haya ido" en el servidor Python/Flask utilizado con poca frecuencia con SQLAlchemy



flask sqlalchemy db relationship (6)

Cuando encontré este error, estaba almacenando una imagen LONGBLOB / LargeBinary ~ 1MB de tamaño. Tuve que ajustar la configuración de configuración max_allowed_packet en MySQL.

Utilicé mysqld --max-allowed-packet=16M

¿Cómo se puede configurar Flask / SQLAlchemy para crear una nueva conexión a la base de datos si no hay una?

Tengo un servidor de Python / Flask visitado con poca frecuencia que usa SQLAlchemy. Se visita cada dos días, y en la primera visita a menudo arroja un error de "servidor MySQL se ha ido". Las siguientes vistas de página están bien, pero parece poco profesional tener este error inicial.

Me gustaría saber la forma correcta de manejar esto: consejos como "hacer un tiempo de espera realmente largo", que sería de unos 4 días en este caso, no parecen correctos. ¿Cómo puedo probar la falta de una conexión de base de datos y crear una si es necesario?


Recientemente me encontré con el mismo problema y encontré este hilo a través de motores de búsqueda conocidos. Leí los documentos de Flask y SQLAlchemy sobre exactamente este tema, los seguí (creo) al pie de la letra, pero fue en vano.

Debajo hay un fragmento que ilustra mi patrón de codificación. Básicamente es esto:

  1. crear sesión como scoped_session
  2. en cada ruta: abrir, usar y cerrar una sesión ()
  3. Haz lo de teardown_appcontext (¿por qué?)

Aquí va:

from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker, scoped_session import flask engine = create_engine("mysql://....") Session = scoped_session(sessionmaker(bind=engine)) app = flask.Flask(__name__) @app.route(''/'') def index(): db = Session() # do stuff db.close() return flask.render_template(''index.html'') @app.teardown_appcontext def shutdown_session(exception=None): Session.remove()



Tuve un problema similar, pero para mí obtendría el error "MySQL se ha ido" en algún momento entre 5 minutos y 2 horas de cada sesión.

Estoy usando Flask-SQLAlchemy por lo que se supone que cierra las conexiones inactivas, pero no parecía estar haciendo eso a menos que la conexión hubiera estado inactiva durante un par de horas.

Finalmente lo reduje a la siguiente configuración de Flask-SQLAlchemy:

app.config[''SQLALCHEMY_POOL_SIZE''] = 100 app.config[''SQLALCHEMY_POOL_RECYCLE''] = 280

La configuración predeterminada para estos son 10 y 7200 (2 horas) respectivamente.

Es una cuestión de jugar con estos ajustes para adaptarse a su entorno.

Por ejemplo, había leído en muchos lugares que SQLALCHEMY_POOL_RECYCLE debería establecerse en 3600, pero eso no funcionó para mí. Estoy alojado en PythonAnywhere y matan conexiones inactivas de MySQL después de 5 minutos (300 segundos). Así que establecer mi valor a menos de 300 resolvió el problema.

Espero que esto ayude a los demás, porque desperdicié MUCHO tiempo en este tema.

http://flask-sqlalchemy.pocoo.org/2.1/config/#configuration-keys


2018 respuesta: en SQLAlchemy v1.2.0 +, tiene disponible la característica de pre-ping del conjunto de conexiones para resolver este problema de "El servidor MySQL se ha ido".

Pre-ping del conjunto de conexiones: el grupo de conexiones ahora incluye una función opcional de "pre ping" que probará la "vitalidad" de una conexión agrupada para cada conexión, reciclando de forma transparente la conexión DBAPI si la base de datos está desconectada. Esta característica elimina la necesidad del indicador de "reciclaje de agrupación", así como el problema de los errores que surgen cuando se utiliza una conexión agrupada después de reiniciar la base de datos.

Las pruebas pesimistas de las conexiones al momento del pago son posibles con el nuevo argumento:

engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True)


He tenido problemas con esto antes, y descubrí que la forma de manejarlo es no mantener las sesiones alrededor. El problema es que estás tratando de mantener una conexión abierta por mucho tiempo. En su lugar, use una sesión de ámbito local de subprocesos como lo hace en __init__.py o en un paquete de utilidad que importe en todas partes:

from sqlalchemy.orm import scoped_session, sessionmaker Session = scoped_session( sessionmaker() )

Luego configura tus motores y metadatos una vez. Esto le permite saltear las mecánicas de configuración cada vez que se conecta / desconecta. Después de eso, puede hacer su trabajo de DB así:

session = Session() someObject = session.query( someMappedClass ).get( someId ) # use session like normal ... session.close()

Si desea aferrarse a objetos viejos y no desea dejar la sesión abierta, puede usar el patrón anterior y reutilizar objetos antiguos como este:

session = Session() someObject = session.merge( someObject ) # more db stuff session.close()

El punto es que desea abrir su sesión, hacer su trabajo y luego cerrar su sesión. Esto evita tiempos de espera muy bien. Hay muchas opciones para .merge y .add que le permiten incluir los cambios que ha realizado en objetos separados o cargar datos nuevos desde el archivo db. Los documentos son muy detallados, pero una vez que sabes lo que estás buscando, puede ser un poco más fácil de encontrar.

Para llegar hasta allí y evitar que MySQL "se vaya", debe resolver el problema de su grupo de conexiones manteniendo las conexiones abiertas por mucho tiempo y revisando una conexión anterior por usted.

Para obtener una conexión nueva, puede configurar la opción pool_recycle en su llamada create_engine . Establezca este pool_recycle en la cantidad de segundos de tiempo en el grupo de conexiones entre los registros que desea que se cree una nueva conexión en lugar de que se devuelva una conexión existente.