2 votes

Comment se reconnecter à postgreSQL dans la classe de connexion threadée de psycopg2 ? Échec causé par une erreur SSL SYSCALL : EOF detected in Azure ?

Notre application fonctionnait bien jusqu'à ce que nous fassions un portage vers la base de données Microsoft pour PostgreSQL dans Azure. Puis, périodiquement, notre application échoue sans raison réelle et nous avons des erreurs SSL SYSCALL partout - sur les DELETE et ainsi de suite. Nous avons essayé tout ce qui est décrit sur Internet - utilisation des args keepalive, RAM, mémoire et tout le reste. Nous voulons essayer de rétablir automatiquement la connexion. Nous voulons essayer de rétablir automatiquement la connexion, mais nous avons un pool de connexion threadé. Psycopg2 reconnexion automatique dans une classe Mais nos fonctions qui lisent la base de données sont dans une autre classe. Nous avons donc deux questions :

1) Quelle est la cause des erreurs SSL SYSCALL ? J'ai cherché dans tous les fils de discussion et les suspects habituels sont écartés. 2) Comment puis-je me reconnecter en cas d'échec à l'intérieur d'une classe de pool de connexion filaire ?

Voici comment notre application est structurée

class DBClass(object):
    _instance = None
    conn= None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = object.__new__(cls)
            try:
                max_conn = 12
                keepalive_args = { "keepalives": 1, "keepalives_idle": 25, "keepalives_interval": 4,"keepalives_count": 9,
                }

                db._instance.pool = psycopg2.pool.ThreadedConnectionPool(3, max_conn, db=,
                                                                               host=, user=,
                                                                               password=,
                                                                               port=, **keepalive_args)

            except Exception as ex:
                db._instance = None
                raise ex

        return cls._instance

    def __enter__(self):
        self.conn= self._instance.pool.getconn()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._instance.pool.putconn(self.connection)

    def __del__(self):
        self._instance.pool.closeall()

Un autre module python a une classe appelée clsEmployee. Nous avons des dizaines de fonctions qui utilisent la classe de base de données mentionnée ci-dessus. Quelque chose comme ça.

    with DBClass() as db:
        pg_conn = db.connection
        cur = pg_conn.cursor()
        cur.execute("SELECT * from emp")
        row = cur.fetchone()[0]

0voto

Michael Robellard Points 1162

Il y a plusieurs façons de gérer cela.

La solution proposée par Psycopg2 reconnexion automatique dans une classe Cela fonctionnera toujours si vos appels pour exécuter le travail de la base de données sont en dehors de la classe DBC. Vous avez juste besoin de fonctions qui appellent la base de données, et vous les enveloppez avec un décorateur. Tout ce que fait le décorateur est d'ajouter une boucle pour permettre à la fonction d'être appelée plusieurs fois, d'envelopper la fonction réelle dans un try/except et de se reconnecter sur un except. Il s'agit en fait d'une façon assez standard de traiter ce type de problème, car elle peut fonctionner pour les bases de données, les API ou tout ce qui peut échouer. La seule chose que vous pouvez vouloir faire est d'ajouter un backoff exponentiel à votre réessai (là où se trouve l'appel de sommeil).

L'autre option consiste à créer votre propre sous-classe de curseur qui possède la même logique de réessai dans une version surchargée de execute. Cela accomplira la même chose, il s'agit juste de savoir ce que vous pensez être le plus facile à utiliser.

Puisque ceci est utilisé dans une application Flask, vous pourriez modifier la première approche et au lieu de faire la répétition au niveau du code du modèle, vous pourriez faire la répétition au niveau de la route Flask.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X