[Python] Mémorandum sur l'évitement des erreurs SQLAlchemy

introduction

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.

Environnement d'exécution

Contre-mesures

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)

Évaluer pool_recycle

[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.

Fermer la session à chaque fois à la fin d'une demande

[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. .. ..

Ping le mysqlserver pour générer un processus

[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()

en conclusion

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.

Les références

--Python: résout le problème du "serveur MySQL a disparu" dans SQLAlchemy (http://blog.amedama.jp/entry/2015/08/15/133322)

Recommended Posts

[Python] Mémorandum sur l'évitement des erreurs SQLAlchemy
#python python évitement des erreurs de syntaxe japonaise
Mémorandum Python
Mémorandum Python 2
Mémorandum Python
mémorandum python
mémorandum python
Mémorandum Python
mémorandum python
Mémorandum Python
Mémorandum de base Python
Mémorandum de Python Pathlib
Mémorandum Python (algorithme)
Gestion des erreurs Python
Mémorandum Python [liens]
Variables de numérotation des mémorandums Python
mémorandum python (mise à jour séquentielle)
Erreur Python non implémentée
Mémorandum Python (signet personnel)
Liste des erreurs Python (japonais)
Mémorandum de base Python partie 2
Mémorandum @ Python OR Séminaire
mémorandum python super basique
[Python] pour une erreur d'instruction
Mémorandum Cisco _ configuration d'entrée avec Python
Mémorandum ABC [ABC163 C --managementr] (Python)
fonction de mémorandum python pour débutant
Mémorandum @ Python OR Séminaire: matplotlib
Mémorandum sur la corrélation [Python]
[youtube-dl] Erreur SSL python3 (CERTIFICATE_VERIFY_FAILED)
Mémorandum @ Python OR Séminaire: Pulp
métaclasse python et déclaration sqlalchemy
Erreur lors de la lecture avec python
Un mémorandum sur le simulacre de Python
Mémorandum @ Python OU Séminaire: Pandas
Mémorandum de gestion des erreurs de construction PyCUDA
[python] Mémorandum de génération aléatoire
Mémorandum @ Python OR Seminar: scikit-learn
Vérification de la version de python de résolution d'erreur
mémorandum d'exécution parallèle / asynchrone python
Mémorandum ABC [ABC159 C - Volume maximum] (Python)
Mémorandum d'opération Excel Python pywin32 (win32com)
Erreur Python: ModuleNotFoundError: aucun module nommé 'flask'
[Python] Un mémorandum de belle soupe4