Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

415
Vistas
matraz_sqlalchemy `pool_pre_ping` solo funciona a veces

Para la prueba, modifico los parámetros de MYSQL (RDS) de la siguiente manera;

wait_timeout = 40 (el valor predeterminado era 28800)

max_allowed_packet = 1 GB (máximo: solo para asegurarse de que el problema no sea causado por paquetes pequeños)

net_read_timeout = 10

tiempo de espera interactivo sin cambios

Luego probé mi aplicación sin las opciones de pool_pre_ping configuradas (el valor predeterminado es Falso), mantuve la aplicación inactiva durante 40 segundos, intenté iniciar sesión y obtuve

 Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: Traceback (most recent call last): Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: File "/var/www/api_server/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: context) Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: File "/var/www/api_server/venv/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 507, in do_execute Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: cursor.execute(statement, parameters) Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: File "/var/www/api_server/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 206, in execute Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: res = self._query(query) Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: File "/var/www/api_server/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 312, in _query Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: db.query(q) Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: File "/var/www/api_server/venv/lib/python3.6/site-packages/MySQLdb/connections.py", line 224, in query Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: _mysql.connection.query(self, query) Nov 14 20:05:20 ip-172-31-33-52 gunicorn[16962]: MySQLdb._exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')

Se agregó pool_pre_ping de esta manera (usando la versión 2.4.1 de flask_sqlalchamy);

 import os from flask import Flask from flask_sqlalchemy import SQLAlchemy as _BaseSQLAlchemy class SQLAlchemy(_BaseSQLAlchemy): def apply_pool_defaults(self, app, options): super(SQLAlchemy, self).apply_pool_defaults(app, options) options["pool_pre_ping"] = True # options["pool_recycle"] = 30 # options["pool_timeout"] = 35 db = SQLAlchemy() class DevConfig(): SQLALCHEMY_ENGINE_OPTIONS = {'pool_recycle': 280, 'pool_timeout': 100, 'pool_pre_ping': True} # These configs doesn't get applied in engine configs :/ DEBUG = True # SERVER_NAME = '127.0.0.1:5000' SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI_DEV') SQLALCHEMY_TRACK_MODIFICATIONS = False config = dict( dev=DevConfig, ) app = Flask(__name__, instance_relative_config=True) app.config.from_object(config['dev']) # INIT DATABASE db.init_app(app) with app.app_context(): db.create_all() -----------run.py app.run(host='127.0.0.1', port=5000)

Con esto, ahora la aplicación web logra obtener una nueva conexión incluso después de que el servidor MySQL haya cerrado la conexión anterior. Siempre funciona bien cuando accedo a la base de datos justo después de que el servidor la cerró (intenté un máximo de 50 segundos después) ... pero cuando mantengo la conexión inactiva durante mucho tiempo (no lo he notado, pero ~> 10-15 min), nuevamente Veo el mismo error.
De acuerdo con los documentos (especialmente la sección Tratar con desconexiones ), la opción pool_pre_ping debería manejar este tipo de escenario en segundo plano. ¿O hay alguna otra variable de tiempo de espera que deba cambiar en el servidor MySQL?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Desde Flask-SQLAlchemy Documentos de configuración :

Ciertos backends de bases de datos pueden imponer diferentes tiempos de espera de conexión inactiva, lo que interfiere con la agrupación de conexiones de Flask-SQLAlchemy.

De forma predeterminada, MariaDB está configurada para tener un tiempo de espera de 600 segundos. Esto a menudo resulta difícil de depurar, el entorno de producción solo tiene excepciones como

2013: Lost connection to MySQL server during query.

Si usa un backend (o una base de datos como servicio preconfigurada) con un tiempo de espera de conexión más bajo, se recomienda que establezca SQLALCHEMY_POOL_RECYCLE en un valor menor que el tiempo de espera de su backend.

El script citado en la pregunta muestra discrepancias entre su MySQL timeout-configs ( wait_timeout , net_read_timeout ) y su SQLAlchemy ( pool_recycle , pool_timeout ) y Flask-SQLAlchemy tiempos de espera ( SQLALCHEMY_POOL_RECYCLE , SQLALCHEMY_POOL_TIMEOUT ).

Podemos resolver esto usando la clase auxiliar DevConfig para coordinar las constantes de configuración de la conexión db en toda la aplicación. Para hacer eso, asignamos nuestra configuración a atributos estáticos y nos referimos a ellos para que no haya expectativas de tiempo de espera en conflicto. Aquí hay una implementación:

 import os from flask import Flask from flask_sqlalchemy import SQLAlchemy as _BaseSQLAlchemy # Coordinate DevConfig with SQLAlchemy and Flask-SQLAlchemy (don't repeat yourself!) class DevConfig(): SQLALCHEMY_POOL_RECYCLE = 35 # value less than backend's timeout SQLALCHEMY_POOL_TIMEOUT = 7 # value less than backend's timeout SQLALCHEMY_PRE_PING = True SQLALCHEMY_ENGINE_OPTIONS = {'pool_recycle': SQLALCHEMY_POOL_RECYCLE, 'pool_timeout': SQLALCHEMY_POOL_TIMEOUT, 'pool_pre_ping': SQLALCHEMY_PRE_PING} DEBUG = True # SERVER_NAME = '127.0.0.1:5000' SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI_DEV') SQLALCHEMY_TRACK_MODIFICATIONS = False class SQLAlchemy(_BaseSQLAlchemy): def apply_pool_defaults(self, app, options): super(SQLAlchemy, self).apply_pool_defaults(app, options) options["pool_pre_ping"] = DevConfig.SQLALCHEMY_PRE_PING # options["pool_recycle"] = 30 # options["pool_timeout"] = 35 db = SQLAlchemy() config = dict( dev=DevConfig, ) app = Flask(__name__, instance_relative_config=True) app.config.from_object(config['dev']) # INIT DATABASE db.init_app(app) with app.app_context(): db.create_all()

Si lo desea, puede verificar la diferencia de los cambios que hice: diffchecker.com/Q1e85Hhc

over 4 years ago · Santiago Trujillo Denunciar

0

Establecí los siguientes ajustes:

 SQLALCHEMY_ENGINE_OPTIONS = { 'pool_size': 10, 'pool_recycle': 60, 'pool_pre_ping': True }

Los últimos meses han dejado de caer...

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda