有没有一种“with conn.cursor() as...”的方式来使用Sqlite?

问题描述 投票:0回答:3

而不是使用:

import sqlite3
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute(...)
c.close()

是否可以使用 Pythonic 习语:

with conn.cursor() as c:
    c.execute(...)

似乎不起作用:

AttributeError: __exit__

注意:由于this,关闭游标非常重要。

python database sqlite with-statement
3个回答
14
投票

您可以使用

contextlib.closing

import sqlite3
from contextlib import closing

conn = sqlite3.connect(':memory:')

with closing(conn.cursor()) as cursor:
    cursor.execute(...)

这是有效的,因为

closing(object)
在 with 块之后自动调用传入对象的
close()
方法。


5
投票

更简单的替代方案是将连接对象与上下文管理器一起使用,如 docs 中所指定。

with con:
    con.execute(...)

如果您坚持使用光标(因为原因),那么为什么不创建自己的包装类呢?

class SafeCursor:
    def __init__(self, connection):
        self.con = connection

    def __enter__(self):
        self.cursor = self.con.cursor()
        return self.cursor

    def __exit__(self, typ, value, traceback):
        self.cursor.close()

然后你可以这样称呼你的班级:

with SafeCursor(conn) as c:
    c.execute(...)

3
投票

添加到sudormrfbin 的帖子。我最近遇到一个问题,其中

INSERT
语句未提交到数据库。 结果我错过了
with
对象的
Connection
上下文管理器。
此外,始终关闭
Cursor
对象也是一个好习惯,如这篇文章中所述。
因此,使用两个
contextlib.closing()
方法,每个方法都位于
with
上下文管理器中:

import contextlib
import sqlite3

# Auto-closes the Connection object
with contextlib.closing(sqlite3.connect("path_to_db_file")) as conn:
    # Auto-commit to the database
    with conn:
        # Auto-close the Cursor object
        with contextlib.closing(conn.cursor()) as cursor:
            # Execute method(s)
            cursor.execute(""" SQL statements here """)
© www.soinside.com 2019 - 2024. All rights reserved.