Claudia, miembro de nuestro equipo, nos ha hecho el favor de escribir esta crónica porque conoce perfectamente dicho tema.
Solución:
Las conexiones tienen un close
como se especifica en PEP-249 (Python Database API Specification 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
Desde el pyodbc
Tanto la conexión como el cursor son administradores de contexto, hoy en día sería más conveniente (y preferible) escribir esto como:
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 `with` statement!!
Consulte https://github.com/mkleehammer/pyodbc/issues/43 para obtener una explicación de por qué no se llama a conn.close().
Tenga en cuenta que, a diferencia del código original, esto provoca conn.commit()
ser llamado. Usa el exterior with
declaración para controlar cuando quieras commit
ser llamado.
También tenga en cuenta que independientemente de si utiliza o no el with
declaraciones, según los documentos,
Las conexiones se cierran automáticamente cuando se eliminan (generalmente cuando quedan fuera del alcance), por lo que normalmente no debería necesitar llamar [
conn.close()
]pero puede cerrar explícitamente la conexión si lo desea.
y de manera similar para los cursores (mi énfasis):
Los cursores se cierran automáticamente cuando se eliminan (por lo general, cuando quedan fuera del alcance), tan llamando [
csr.close()
] no suele ser necesario.
Puede envolver toda la conexión en un administrador de contexto, como el siguiente:
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()
Luego haga algo como esto donde necesite una conexión a la base de datos:
with open_db_connection("...") as cursor:
# Your code here
La conexión se cerrará cuando dejes el bloque with. Esto también revertirá la transacción si ocurre una excepción o si no abrió el bloque usando with open_db_connection("...", commit=True)
.
Puede intentar desactivar la agrupación, que está habilitada de forma predeterminada. Consulte esta discusión para obtener más información.
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
Recuerda que tienes concesión de valorar esta crónica si te fue de ayuda.