如果我不closuresPython SQLite中的数据库连接,该怎么办?

我正在做这样的事情…

conn = sqlite3.connect(db_filename) with conn: cur = conn.cursor() cur.execute( ... ) 

with自动提交更改。 但是文档没有提到closures连接。

其实我可以在后面的陈述中使用conn (我已经testing过)。 因此,似乎上下文pipe理器不closures连接。

我必须手动closures连接吗? 如果我把它打开呢?

编辑

我的结论是…

  • 上下文pipe理器中的连接没有closures ,我已经testing并确认了它。 在__exit__ ,上下文pipe理器只通过conn.commit()提交更改
  • with connwith sqlite3.connect(db_filename) as conn同一件事情 。 所以使用任何一个仍然保持连接活着
  • with语句不会创build一个新的作用域,因此在该成员之内创build的所有variables都可以在其外部访问
  • 最后,你应该手动closures连接

在回答关于如果不closuresSQLite数据库会发生什么的具体问题时,答案非常简单,适用于在任何编程语言中使用SQLite。 当连接被代码明确地closures或者被程序退出隐式closures时,任何未完成的事务被回滚。 (回滚实际上是由下一个程序来打开数据库。)如果没有未完成的事务打开,则什么都不会发生。

这意味着您不必过多地关心在进程退出之前closures数据库,并且您应该注意事务,确保在适当的时候启动它们并进行提交。

您在这里有一个有效的潜在关注点,但是了解sqlite如何运作也很重要:

 1. connection open 2. transaction started 3. statement executes 4. transaction done 5. connection closed 

数据正确性方面 ,您只需要担心事务而不是打开句柄。 sqlite只在一个事务(*)或语句执行中的数据库上保存一个锁。

不过就资源pipe理而言 ,例如,如果您打算删除sqlite文件或使用如此多的连接,则可能会耗尽文件描述符,但是您也关心打开事务外连接。

有两种方法closures连接:要么显式地调用.close()之后,仍然有句柄,但是不能使用它,或者让连接超出范围并进行垃圾回收。

如果您必须closures连接 ,请按照Python的格言“ 显式优于隐式明确 closures连接

如果你只是检查代码副作用,让最后一个variables保持引用连接超出范围可能是可以接受的,但请记住,exception捕获堆栈,从而引用该堆栈。 如果你周围传递exception,连接的生命周期可能会被任意地延长。

警告编程器 ,sqlite默认使用“延迟”事务,也就是说事务只在执行语句时启动。 在上面的例子中,事务运行从3到4,而不是从2到4。

你可以像这样使用块:

 from contextlib import closing import sqlite3 def query(self, db_name, sql): with closing(sqlite3.connect(db_name)) as con, con, \ closing(con.cursor()) as cur: cur.execute(sql) return cur.fetchall() 
  • 所连接
  • 开始交易
  • 创build一个数据库游标
  • 执行操作并返回结果
  • closures光标
  • 提交/回滚交易
  • closures连接

在快乐和特殊情况下都是安全的

连接使用后,您的版本将保留在范围内。

例:

你的版本

  conn = sqlite3.connect(db_filename) #DECLARE CONNECTION OUT OF WITH BLOCK with conn: #USE CONNECTION IN WITH BLOCK cur = conn.cursor() cur.execute( ... ) #conn variable is still in scope, so you can use it again 

新版本

  with sqlite3.connect(db_filename) as conn: #DECLARE CONNECTION AT START OF WITH BLOCK cur = conn.cursor() cur.execute( ... ) #conn variable is out of scope, so connection is closed # MIGHT BE IT IS NOT CLOSED BUT WHAT Avaris SAID! #(I believe auto close goes for with block) 

为了pipe理与数据库的连接,我通常会这样做,

 # query method belonging to a DB manager class def query (self, sql): con = sqlite3.connect(self.dbName) with con: cur = con.cursor() cur.execute(sql) res = cur.fetchall() if con: con.close() return res 

这样做,我确信连接是明确的closures。