如果我不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 conn
和with 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。