Соединение с базой данных Python Закрыть

Используя приведенный ниже код, я покинул меня с открытым подключением, как мне закрыть?

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

Ответ 1

Соединения имеют метод close, как указано в PEP-249 (спецификация API базы данных 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

Поскольку pyodbc соединение и курсор оба являются менеджерами контекста, в настоящее время было бы удобнее (и предпочтительнее) написать это следующим образом:

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!! 

Смотрите https://github.com/mkleehammer/pyodbc/issues/43 объяснение, почему conn.close() не вызывается.

Обратите внимание, что в отличие от исходного кода, это вызывает conn.commit() для вызова. Используйте внешний оператор with, чтобы контролировать, когда вы хотите, чтобы вызывался commit.


Также обратите внимание, что независимо от того, используете ли вы операторы with, для документов,

Соединения автоматически закрываются, когда они удаляются (обычно, когда они выходят за пределы области видимости), поэтому вам обычно не нужно вызывать [conn.close()], но вы можете явно закрыть соединение, если хотите.

и аналогично для курсоров (мой акцент):

Курсоры закрываются автоматически, когда они удаляются (обычно, когда они выходят за пределы области видимости), поэтому вызов [csr.close()] обычно не требуется.

Ответ 2

Вы можете обернуть все соединение в диспетчере контекста, например, следующим образом:

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

Затем сделайте что-нибудь подобное, когда вам понадобится соединение с базой данных:

with open_db_connection("...") as cursor:
    # Your code here

Соединение будет закрыто при выходе из блока. Это также приведет к откату транзакции, если произойдет исключение, или если вы не открыли блок с помощью with open_db_connection("...", commit=True).

Ответ 3

Возможно, вы попытаетесь отключить пул, который включен по умолчанию. См. этот обсуждение для получения дополнительной информации.

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

Ответ 4

Согласно документации pyodbc, по умолчанию не закрыты соединения с SQL-сервером . Некоторые драйверы баз данных не закрывают соединения, когда close() вызывается для того, чтобы сохранить округление до сервера.

Чтобы закрыть соединение, когда вы вызываете close(), вы должны установить пул в False:

import pyodbc

pyodbc.pooling = False