25

我在做一个教程,遇到了一种处理与 sqlite3 的连接的方法,然后我研究了 WITH 关键字,发现它是尝试的替代方法,除了,finally 做事的方法

据说在文件处理的情况下,“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 而不是 TRY CATCH 的话。

并且应该在每个查询上打开和关闭连接吗?(我在一个函数中制定查询,每次都用一个参数调用)这是一个好习惯吗?

4

3 回答 3

22

一般来说,上下文管理器在使用时可以自由地执行其作者希望它执行的任何操作。设置/重置某个系统状态,使用后清理资源,获取/释放锁等。

特别是,正如Jon 已经写的那样,数据库连接对象在用作上下文管理器时会创建一个事务。如果你想自动关闭连接,你可以这样做

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
于 2013-10-22T17:38:08.280 回答
16

来自文档:http ://docs.python.org/2/library/sqlite3.html#using-the-connection-as-a-context-manager

连接对象可以用作自动提交或回滚事务的上下文管理器。如果发生异常,事务回滚;否则,事务被提交:

因此,上下文管理器不会释放连接,而是确保在发生任何异常时回滚连接上发生的任何事务,或者以其他方式提交......例如对DELETE,UPDATEINSERT查询很有用。

于 2013-10-22T15:51:19.027 回答
13

您还可以围绕 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

于 2018-06-01T14:19:57.507 回答