问题 如何判断Python SQLite数据库连接或游标是否已关闭?


假设您有以下代码:

import sqlite3

conn = sqlite3.connect('mydb')
cur = conn.cursor()
# some database actions
cur.close()
conn.close()
# more code below

如果我尝试使用 conn 要么 cur 以后的对象,我怎么能告诉它们已经关闭?我找不到了 .isclosed() 方法或类似的东西。


4040
2017-12-30 17:36


起源



答案:


你可以包装一个 try, except 声明:

>>> conn = sqlite3.connect('mydb')
>>> conn.close()
>>> try:
...   resultset = conn.execute("SELECT 1 FROM my_table LIMIT 1;")
... except sqlite3.ProgrammingError as e:
...   print e
Cannot operate on a closed database.

这依赖于 特定于sqlite3的快捷方式


10
2017-12-30 18:10



该方法是理智的,但避免做一个 SELECT * FROM mytable 虽然你可以做得更轻 SELECT one_column FROM mytable LIMIT 1。前者是非常低效的,你有一个非小型数据库。 - Antoine P.
感谢@pitrou,更新以考虑到这一点。 - bernie
@AntoineP。您将SQLite与其他数据库混淆。 SQLite完成的工作量没有差异。它不会预先计算查询的所有结果 - 相反,它可以为第一个结果行提供最少量的工作。第二个结果行只有在您要求时才会计算出来。因此限制无效。无论如何,更好的查询是不依赖于模式的查询 - 例如PRAGMA user_version。 - Roger Binns
谢谢@RogerBinns,补充一下 - bernie


答案:


你可以包装一个 try, except 声明:

>>> conn = sqlite3.connect('mydb')
>>> conn.close()
>>> try:
...   resultset = conn.execute("SELECT 1 FROM my_table LIMIT 1;")
... except sqlite3.ProgrammingError as e:
...   print e
Cannot operate on a closed database.

这依赖于 特定于sqlite3的快捷方式


10
2017-12-30 18:10



该方法是理智的,但避免做一个 SELECT * FROM mytable 虽然你可以做得更轻 SELECT one_column FROM mytable LIMIT 1。前者是非常低效的,你有一个非小型数据库。 - Antoine P.
感谢@pitrou,更新以考虑到这一点。 - bernie
@AntoineP。您将SQLite与其他数据库混淆。 SQLite完成的工作量没有差异。它不会预先计算查询的所有结果 - 相反,它可以为第一个结果行提供最少量的工作。第二个结果行只有在您要求时才会计算出来。因此限制无效。无论如何,更好的查询是不依赖于模式的查询 - 例如PRAGMA user_version。 - Roger Binns
谢谢@RogerBinns,补充一下 - bernie


如何确保连接和光标永远不会关闭?

你可以有一个基于状态的程序,你可以保证只在正确的时间调用close()。

或者将它们包装在具有pass实现的其他对象中 close()。或者添加一个 _isclosed 成员设置 close() 和访问 isclosed()


0
2017-12-30 18:54