L'utilisation du code ci-dessous me laisse une connexion ouverte, comment fermer?
import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest')
csr = conn.cursor()
csr.close()
del csr
Les connexions ont une méthode close
comme spécifié dans PEP-249 (spécification de l'API de la base de données Python v2.0):
import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest')
csr = conn.cursor()
csr.close()
conn.close() #<--- Close the connection
Étant donné que pyodbc
connexion et curseur sont tous deux des gestionnaires de contexte, de nos jours, il serait plus pratique (et préférable) d'écrire ceci comme:
import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest')
with conn:
crs = conn.cursor()
do_stuff
# conn.commit() will automatically be called when Python leaves the outer `with` statement
# Neither crs.close() nor conn.close() will be called upon leaving the the `with` statement!!
Voir https://github.com/mkleehammer/pyodbc/issues/4 pour une explication des raisons pour lesquelles conn.close () n'est pas appelé.
Notez que contrairement au code d'origine, cela provoque l'appel de conn.commit()
. Utilisez l'instruction with
externe pour contrôler quand vous voulez que commit
soit appelé.
Notez également que, que vous utilisiez ou non les instructions with
, par the docs ,
Les connexions sont automatiquement fermées lorsqu'elles sont supprimées (généralement lorsqu'elles sortent du champ d'application), vous ne devriez donc normalement pas avoir besoin d'appeler [
conn.close()
], mais vous pouvez explicitement fermer la connexion si vous le souhaitez.
et de même pour les curseurs (c'est moi qui souligne):
Les curseurs sont fermés automatiquement lorsqu'ils sont supprimés (généralement lorsqu'ils sortent du champ d'application), , donc appeler [
csr.close()
] n'est généralement pas nécessaire .
Vous pouvez envelopper toute la connexion dans un gestionnaire de contexte, comme suit:
from contextlib import contextmanager
import pyodbc
import sys
@contextmanager
def open_db_connection(connection_string, commit=False):
connection = pyodbc.connect(connection_string)
cursor = connection.cursor()
try:
yield cursor
except pyodbc.DatabaseError as err:
error, = err.args
sys.stderr.write(error.message)
cursor.execute("ROLLBACK")
raise err
else:
if commit:
cursor.execute("COMMIT")
else:
cursor.execute("ROLLBACK")
finally:
connection.close()
Ensuite, faites quelque chose comme ça partout où vous avez besoin d'une connexion à une base de données:
with open_db_connection("...") as cursor:
# Your code here
La connexion se fermera lorsque vous quitterez le bloc with. Cela annulera également la transaction si une exception se produit ou si vous n'avez pas ouvert le bloc à l'aide de with open_db_connection("...", commit=True)
.
Vous pouvez essayer de désactiver le regroupement, qui est activé par défaut. Voir la discussion this pour plus d'informations.
import pyodbc
pyodbc.pooling = False
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest')
csr = conn.cursor()
csr.close()
del csr
Selon la documentation de pyodbc, les connexions au serveur SQL ne sont pas fermées par défaut. Certains pilotes de base de données ne ferment pas les connexions lorsque close () est appelé afin d'économiser les allers-retours au serveur.
Pour fermer votre connexion lorsque vous appelez close () , vous devez définir la mise en pool sur False:
import pyodbc
pyodbc.pooling = False