Подключение к базе данных Python Закрыть - PullRequest
40 голосов
/ 24 сентября 2010

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

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

Ответы [ 4 ]

48 голосов
/ 24 сентября 2010

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

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

46 голосов
/ 24 сентября 2010

Соединения имеют метод 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 connection и курсор оба являются менеджерами контекста, в настоящее время было бы удобнее (и предпочтительнее) записать это как:

import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest') 
with conn:
    with conn.cursor() as crs:
        do_stuff
        # crs.close() will automatically be called when Python leaves the inner `with` statement
    # conn.commit() will automatically be called when Python leaves the outer `with` statement

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


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

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

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

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

6 голосов
/ 24 сентября 2010

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

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
3 голосов
/ 07 марта 2017

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

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

import pyodbc

pyodbc.pooling = False
...