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

Aav*_*aas 11 python sqlite python-2.7

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

有人说,在文件处理的情况下,'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
Run Code Online (Sandbox Code Playgroud)

哪个输出

(1, u'3.6.21')
(2, u'3.6.21')
Run Code Online (Sandbox Code Playgroud)

我不知道WITH在这里做了什么(或者一般情况下),所以,如果你愿意,请详细说明在这种情况下使用WITH over TRY CATCH.

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

glg*_*lgl 13

通常,上下文管理器可以自由地执行作者在使用时要执行的任何操作.设置/重置某个系统状态,使用后清理资源,获取/释放锁定等.

特别是,正如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
Run Code Online (Sandbox Code Playgroud)

  • 在 python 3 中,这似乎给出了“AttributeError: 'sqlite3.Connection' object has no attribute 'fetchone'”。/sf/answers/3325093621/ 似乎解决了问题 (2认同)

DSc*_*idt 11

您还可以围绕 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])
Run Code Online (Sandbox Code Playgroud)

https://docs.python.org/2.5/whatsnew/pep-343.html#SECTION000910000000000000000

  • @cikatomo `with` 只做我们告诉它做的事情。`SQLite` 类告诉 `with` 做什么。如果你想要 `with` 提交,你必须在 `__exit__()` 上执行 (2认同)

Jon*_*nts 9

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

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

所以,上下文管理器不释放连接,相反,它保证了在连接上发生的任何交易都将回滚如果出现任何异常,或承诺,否则......有用的DELETE,UPDATEINSERT例如查询.

  • 您正在阅读的教程有点误导。使用默认上下文管理器时,不会显式关闭连接。您可能想看看`contextlib. opening`... (2认同)