J'utilise généralement SQLAlchemy lorsque je frappe MySQL depuis python. Je ne suis pas particulièrement gêné lors du développement en Local, mais après le déploiement avec uwsgi dans un environnement proche de la production, le phénomène de panne du système en raison d'une erreur mystérieuse s'est produit fréquemment.
_mysql_exceptions.OperationalError: (2006, 'MySQL server has gone away')
Et
_mysql_exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')
Et
sqlalchemy.exc.StatementError: (sqlalchemy.exc.InvalidRequestError) Can't reconnect until invalid transaction is rolled back
Et cette erreur ...
SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request
Après enquête, de nombreuses personnes ont rencontré ce problème et se sont vu proposer diverses solutions, mais comme c'est différent selon le blog, je l'ai essayé depuis le début.
Je laisserai un mémorandum de ce qui a fonctionné, mais comme c'est un mystère quant à la vérité, j'apprécierais que vous puissiez me dire si cela semble faux.
En principe, partez de l'endroit où le moteur et la session sont créés comme suit.
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker
metadata = MetaData()
engine = create_engine(uri, encoding='utf-8', pool_recycle=3600)
session = scoped_session(sessionmaker(autocommit=False,
expire_on_commit = False,
autoflush=True,
bind=_engine))
metadata.create_all(bind=engine)
[Référence] Python: Résolvez le problème du "serveur MySQL a disparu" dans SQLAlchemy
Selon le site de référence, cette erreur
Se produit lorsque SQLAlchemy émet une instruction SQL alors que la connexion à MySQL a expiré
Donc, vérifiez d'abord le wait_timeout du côté MySQL et spécifiez une valeur plus petite dans pool_recycle
.
Vérifiez le paramètre wait_timeout du côté SQL et vérifiez
> show global variables like 'wait_timeout';
+--------------------------+----------+
| Variable_name | Value |
+--------------------------+----------+
| innodb_lock_wait_timeout | 50 |
| lock_wait_timeout | 31536000 |
| wait_timeout | 600 |
+--------------------------+----------+
3 rows in set (0.00 sec)
Il a été rendu plus petit que le temps spécifié de pool_recycle
(60 pour l'essai cette fois). J'ai senti que le nombre d'erreurs avait un peu diminué, mais le problème persistait et j'ai cherché une autre méthode.
[Référence] [Python] Lutte contre l'alchimie SQL
Selon le site de référence, il est important d'éviter l'omission de clôture de session
@app.teardown_appcontext
def session_clear(exception):
if exception and session.is_active:
session.rollback()
else:
session.commit()
session.close()
@ App.teardown_appcontext
de Flask est appelé à chaque fois à la fin de la requête, fermez donc explicitement la session ici.
La plupart des erreurs ont disparu jusqu'à présent, mais parfois SQL disparaît.
SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request
Ne disparaît pas quoi qu'il arrive. .. ..
[Référence] Le serveur MySQL a disparu avec Flask et SQL Alchemy
C'est le dernier moyen d'y arriver, et si la connexion est fermée, démarrez d'abord le processus à l'avance. Est-ce la méthode? Pour le moment, toutes les erreurs ont été résolues.
from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy.pool import Pool
@event.listens_for(Pool, "checkout")
def ping_connection(dbapi_connection, connection_record, connection_proxy):
cursor = dbapi_connection.cursor()
try:
cursor.execute("SELECT 1")
except:
raise exc.DisconnectionError()
cursor.close()
Il existe de nombreux sites qui mentionnent ce problème, mais j'ai essayé et cité ceux qui ont fonctionné. Le site que j'ai cité cette fois a également divers processus d'essais et d'erreurs, donc si vous êtes coincé avec des problèmes similaires, je pense que vous devriez vous y référer également. S'il existe un meilleur moyen, ou si la cause fondamentale n'est pas là en premier lieu, veuillez me le faire savoir.
--Python: résout le problème du "serveur MySQL a disparu" dans SQLAlchemy (http://blog.amedama.jp/entry/2015/08/15/133322)
Recommended Posts