Python数据库连接关闭

100 投票
6 回答
218210 浏览
提问于 2025-04-16 04:31

使用下面的代码后,我发现连接一直是打开的,我该怎么关闭它呢?

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

6 个回答

8

你可以试着关闭连接池,因为默认情况下是开启的。想了解更多信息,可以查看这个讨论

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
67

你可以把整个数据库连接放在一个上下文管理器里,像下面这样:

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”块的时候,连接会自动关闭。如果在这个过程中发生了错误,或者你没有用 with open_db_connection("...", commit=True) 来打开这个块,那么这个连接会回滚之前的操作。

149

连接对象有一个close方法,这个方法是根据PEP-249(Python数据库API规范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 `with` statement!! 

想了解为什么不调用conn.close(),可以查看这个链接

需要注意的是,与原来的代码不同,这样做会导致调用conn.commit()。可以使用外层的with语句来控制你希望何时调用commit


另外,无论你是否使用with语句,根据文档

连接在被删除时会自动关闭(通常是当它们超出作用域时),所以通常情况下你不需要手动调用[conn.close()],但如果你愿意,也可以显式地关闭连接。

同样的情况也适用于游标(我强调一下):

游标在被删除时会自动关闭(通常是当它们超出作用域时),所以通常不需要调用[csr.close()]。

撰写回答