90 votes

Comment fermer une connexion sqlalchemy dans MySQL ?

Voici un exemple de code que j'aimerais exécuter :

for i in range(1,2000):
    db = create_engine('mysql://root@localhost/test_database')
    conn = db.connect()
    #some simple data operations
    conn.close()
    db.dispose()

Existe-t-il un moyen d'exécuter cette opération sans obtenir les erreurs "Too many connections" de MySQL ? Je sais déjà que je peux gérer la connexion autrement ou avoir un pool de connexion. J'aimerais juste comprendre comment fermer correctement une connexion depuis sqlalchemy. Merci d'avance !

173voto

zzzeek Points 22617

Voici comment écrire ce code correctement :

db = create_engine('mysql://root@localhost/test_database')
for i in range(1,2000):
    conn = db.connect()
    #some simple data operations
    conn.close()
db.dispose()

C'est-à-dire que le Engine es un usine pour les connexions ainsi qu'un piscine des connexions, pas la connexion elle-même. Quand vous dites conn.close() la connexion est renvoyé au pool de connexion dans le moteur pas vraiment fermé.

Si vous souhaitez que la connexion soit réellement fermée, c'est-à-dire qu'elle ne soit pas mise en commun, désactivez la mise en commun en utilisant la commande NullPool :

from sqlalchemy.pool import NullPool
db = create_engine('mysql://root@localhost/test_database', poolclass=NullPool)

Avec ce qui précède Engine chaque appel à conn.close() fermera la connexion DBAPI sous-jacente.

Si par contre vous voulez réellement vous connecter à différents à chaque appel, c'est à dire que vos bases de données codées en dur "localhost/test_database" n'est qu'un exemple et que vous avez en fait beaucoup de bases de données différentes, alors l'approche qui utilise dispose() est bien ; il fermera toutes les connexions qui ne sont pas extraites du pool.

Dans tous les cas susmentionnés, l'important est que la Connection est fermé via close() . Si vous utilisez un type d'exécution "sans connexion", c'est-à-dire engine.execute() o statement.execute() le ResultProxy renvoyé par cet appel d'exécution doit être entièrement lu, ou bien fermé explicitement par l'intermédiaire de la fonction close() . A Connection o ResultProxy qui est encore ouverte, interdira le NullPool o dispose() des approches de la fermeture de chaque dernière connexion.

8voto

Romuald Brunet Points 1062

J'ai essayé de trouver une solution pour me déconnecter de la base de données pour un problème sans rapport (il faut se déconnecter avant de bifurquer).

Vous devez invalider la connexion à partir du pool de connexion également.

Dans votre exemple :

for i in range(1,2000):
    db = create_engine('mysql://root@localhost/test_database')
    conn = db.connect()
    # some simple data operations
    # session.close() if needed
    conn.invalidate()
    db.dispose()

0voto

wooper Points 1

Dans mon cas, cela fonctionne toujours et je suis capable de fermer ! Donc l'utilisation de invalidate() avant close() fait l'affaire. Sinon, close() ne fonctionne pas.

conn = engine.raw_connection()  
conn.get_warnings  = True
curSql = xx_tmpsql
myresults = cur.execute(curSql, multi=True)
print("Warnings: #####")
print(cur.fetchwarnings())
for curresult in myresults:
    print(curresult)
    if curresult.with_rows:
        print(curresult.column_names)
        print(curresult.fetchall())
    else:
        print("no rows returned")
cur.close()
conn.invalidate()
conn.close()     
engine.dispose()

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