1

我正在处理一些连接到 sqlite 数据库的代码。在调试所述代码的过程中,我遇到了挂起与数据库的打开连接的问题,因为某些错误阻止了关闭命令的执行。因为 db 和 c 是在函数中定义的,所以我无法从命令行找到并关闭这些对象。它们就像孤立的连接或其他东西,但无论如何它们都会阻止我对数据库做任何其他事情,直到我关闭并重新打开我的交互式控制台。这是它的样子:

def something()
    db=sqlite3.connect('mydatabase')
    c=db.cursor()

    somecode
    lots of different things happening in here
    this may have errors
    thus stopping execution

    db.commit()
    c.close()
    db.close()

我已经在“finally”块中尝试了一个带有最终关闭操作的 try/except 子句,但这可以防止在我调试时将异常引发回交互式输出,并且事情会“默默地”失败(也许我不是做那部分对吗?)。有一个更好的方法吗?

4

3 回答 3

5

通常最好使用 with...as 语句:

with sqlite.connect(...) as db:
    with db.cursor() as c:
        ...

with语句保证 close() 将在 with 语句结束或引发异常时在对象上调用。甚至当从内部调用 return 或 yield 时。

在这里阅读更多:http: //docs.python.org/2/reference/compound_stmts.html#with

于 2013-03-21T15:25:42.747 回答
3

正如 Piotr 所指出的,使用 with 语句可以提高代码的效率,尽管它不会显式关闭与数据库的连接,如果这是用户想要的。这是由一个类似的问题在这里找到的。

如果 with 语句中的代码块执行没有错误,则使用 with 语句的作用是运行 con.commit() 方法;如果遇到异常,则使用 con.rollback() 方法。

来自http://docs.python.org/2/library/sqlite3.html的示例

import sqlite3

con = sqlite3.connect(":memory:")
con.execute("create table person (id integer primary key, firstname varchar unique)")

with con:
    con.execute("insert into person(firstname) values (?)", ("Joe",))

# If Successful, con.commit() is called automatically afterwards
# else con.rollback() is called after the with block finishes with an exception, 
# the exception is still raised and must be caught

try:
    with con:
        con.execute("insert into person(firstname) values (?)", ("Joe",))
except sqlite3.IntegrityError:
    print "couldn't add Joe twice"

注意快捷方法 con.execute() 的使用,它是数据库连接对象的一种方法。这隐式地为您创建游标对象并返回结果,因此需要编写的代码更少。

于 2013-07-03T10:30:49.457 回答
0

要清理资源,请 finally使用:

db = sqlite.connect(...)
try:
    ...
    c = db.cursor()
    try:
        ...
    finally:
        c.close()
    ...
finally:
    db.close()
于 2013-03-21T15:19:44.990 回答