我应该为每个Sqlite3事务调用connect()和close()吗?

gwg*_*gwg 2 python sqlite

我想编写一个Python模块来抽象出我的应用程序的数据库事务.我的问题是我是否需要打电话connect()close()每笔交易?在代码中:

import sqlite3

# Can I put connect() here?
conn = sqlite3.connect('db.py')

def insert(args):
    # Or should I put it here?
    conn = sqlite3.connect('db.py')
    # Perform the transaction.
    c = conn.cursor()
    c.execute(''' insert args ''')
    conn.commit()
    # Do I close the connection here?
    conn.close()

# Or can I close the connection whenever the application restarts (ideally, very rarely)
conn.close()
Run Code Online (Sandbox Code Playgroud)

我对数据库的经验不多,所以我很欣赏为什么一种方法优于另一种方法的解释.

Ale*_*lli 5

使用单个连接会更快,并且操作上应该没问题。

atexit如果您想确保最终发生关闭(即使您的程序因异常而终止),请使用该模块。具体来说,import atexit在程序开始时,就atexit.register(conn.close)您之后connect- 请注意,不是 ()after close,您想要注册要在程序存在时调用的函数(无论是正常还是通过异常),而不是调用该函数。

不幸的是,如果 Python 由于 Python 无法捕获的 C 编码模块中的错误或 等而崩溃kill -9,则注册的退出函数可能最终不会被调用。幸运的是,在这种情况下,无论如何它都不会造成伤害(人们希望,这是一种罕见且极端的情况)。


che*_*ner 5

您可以重复使用相同的连接.您还可以使用连接(和游标)作为上下文管理器,这样您就不需要显式调用它们close.

def insert(conn, args):
    with conn.cursor() as c:
        c.execute(...)
    conn.commit()

with connect('db.py') as conn:
    insert(conn, ...)
    insert(conn, ...)
    insert(conn, ...)
Run Code Online (Sandbox Code Playgroud)

没有理由关闭与数据库的连接,每次重新打开连接可能很昂贵.(例如,您可能需要建立TCP会话以连接到远程数据库.)