Estoy desarrollando una aplicación basada en web usando Python, Flask, MySQL y uWSGI. Sin embargo, no estoy usando SQL Alchemy ni ningún otro ORM. Estoy trabajando con una base de datos preexistente de una aplicación PHP antigua que de todos modos no funcionaría bien con un ORM, así que solo estoy usando mysql-connector y escribiendo consultas a mano.
La aplicación funciona correctamente cuando la inicio por primera vez, pero cuando vuelvo a la mañana siguiente me doy cuenta de que se ha estropeado. Obtendré errores como mysql.connector.errors.InterfaceError: 2013: Lost connection to MySQL server during query o similar mysql.connector.errors.OperationalError: 2055: Lost connection to MySQL server at '10.0.0.25:3306', system error: 32 Broken pipe .
He estado investigando y creo que sé cuál es el problema. Simplemente no he sido capaz de encontrar una buena solución. Lo mejor que puedo imaginar, el problema es el hecho de que mantengo una referencia global a la conexión de la base de datos, y dado que la aplicación Flask siempre se ejecuta en el servidor, eventualmente esa conexión caduca y se vuelve inválida.
Me imagino que sería bastante simple simplemente crear una nueva conexión para cada consulta, pero eso parece una solución lejos de ser ideal. Supongo que también podría construir algún tipo de mecanismo de almacenamiento en caché de conexión que cerraría la conexión anterior después de una hora más o menos y luego la volvería a abrir. Esa es la mejor opción que se me ha ocurrido, pero sigo sintiendo que debería haber una mejor.
Miré a mi alrededor y la mayoría de las personas que han recibido estos errores tienen tablas enormes o dañadas, o algo por el estilo. Ese no es el caso aquí. La antigua aplicación PHP todavía funciona bien, todas las tablas tienen menos de 50,000 filas y menos de 30 columnas, y la aplicación Python funciona bien hasta que se ha sentado durante aproximadamente un día.
Por lo tanto, aquí está la esperanza de que alguien tenga una buena solución para mantener una conexión continuamente abierta a una base de datos MySQL. O tal vez estoy ladrando al árbol equivocado por completo, si es así, espero que alguien lo sepa.
Tengo que trabajar ahora. El uso de conexiones agrupadas pareció solucionar el problema para mí.
mysql.connector.connect( host='10.0.0.25', user='xxxxxxx', passwd='xxxxxxx', database='xxxxxxx', pool_name='batman', pool_size = 3 ) def connection(): """Get a connection and a cursor from the pool""" db = mysql.connector.connect(pool_name = 'batman') return (db, db.cursor()) Llamo a connection() antes de cada función de consulta y luego cierro el cursor y la conexión antes de regresar. Parece funcionar. Todavía abierto a una mejor solución sin embargo.
Desde entonces he encontrado una solución mejor. (Todavía ocasionalmente tenía problemas con las conexiones agrupadas). En realidad, hay una biblioteca dedicada para que Flask maneje las conexiones mysql, que es casi un reemplazo directo.
Desde bash: pip install Flask-MySQL
Agregue MYSQL_DATABASE_HOST , MYSQL_DATABASE_USER , MYSQL_DATABASE_PASSWORD , MYSQL_DATABASE_DB a su configuración de Flask. Luego, en el archivo principal de Python que contiene su objeto Flask App:
from flaskext.mysql import MySQL mysql = MySQL() mysql.init_app(app) Y para obtener una conexión: mysql.get_db().cursor()
El resto de la sintaxis es la misma y no he tenido ningún problema desde entonces. He estado usando esta solución durante mucho tiempo.