我正在做一个教程,并遇到了一种处理sqlite3连接的方法, 然后我研究了WITH关键字并发现它是一种替代尝试,除了最后的做事方式
有人说,在文件处理的情况下,'WITH'会自动处理文件的关闭,我认为与zetcode教程中所说的连接类似: -
“使用with关键字,Python解释器会自动释放 资源。它还提供错误处理。“http://zetcode.com/db/sqlitepythontutorial/
所以我认为使用这种处理方式会很好,但我无法弄清楚为什么两个(内部范围和外部范围)语句都有效? WITH不应该释放连接吗?
import sqlite3
con = sqlite3.connect('test.db')
with con:
cur = con.cursor()
cur.execute('SELECT 1,SQLITE_VERSION()')
data = cur.fetchone()
print data
cur.execute('SELECT 2,SQLITE_VERSION()')
data = cur.fetchone()
print data
输出
(1, u'3.6.21')
(2, u'3.6.21')
我不知道WITH在这里做了什么(或者一般情况下),所以,如果你愿意请详细说明在这种情况下使用WITH over TRY CATCH。
是否应该在每次查询时打开和关闭连接? (我在一个函数内部构造查询,我每次都用一个参数调用它)这是一个好习惯吗?
答案 0 :(得分:9)
通常,上下文管理器可以自由地执行作者在使用时要做的任何事情。设置/重置某个系统状态,使用后清理资源,获取/释放锁等等
特别是,作为Jon already writes,数据库连接对象在用作上下文管理器时会创建一个事务。如果要自动关闭连接,可以执行
with contextlib.closing(sqlite3.connect('test.db')) as con:
with con as cur:
cur.execute('SELECT 1,SQLITE_VERSION()')
data = cur.fetchone()
print data
with con as cur:
cur.execute('SELECT 2,SQLITE_VERSION()')
data = cur.fetchone()
print data
答案 1 :(得分:6)
来自文档:http://docs.python.org/2/library/sqlite3.html#using-the-connection-as-a-context-manager
连接对象可以用作自动提交或回滚事务的上下文管理器。如果发生异常,则回滚事务;否则,交易已经提交:
因此,上下文管理器不会释放连接,相反,它确保在发生任何异常时回滚连接上发生的任何事务,或者以其他方式提交...对{例如{1}},DELETE
和UPDATE
查询。
答案 2 :(得分:1)
你也可以在sqlite3周围编写自己的包装来支持with
:
class SQLite():
def __init__(self, file='sqlite.db'):
self.file=file
def __enter__(self):
self.conn = sqlite3.connect(self.file)
self.conn.row_factory = sqlite3.Row
return self.conn.cursor()
def __exit__(self, type, value, traceback):
self.conn.commit()
self.conn.close()
with SQLite('test.db') as cur:
print(cur.execute('select sqlite_version();').fetchall()[0][0])
https://docs.python.org/2.5/whatsnew/pep-343.html#SECTION000910000000000000000