在python中使用带有“WITH”关键字的sqlite3

时间:2013-10-22 15:45:51

标签: python python-2.7 sqlite

我正在做一个教程,并遇到了一种处理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。

是否应该在每次查询时打开和关闭连接? (我在一个函数内部构造查询,我每次都用一个参数调用它)这是一个好习惯吗?

3 个答案:

答案 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}},DELETEUPDATE查询。

答案 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