【问题标题】:Using a "with" contextmanager with pysqlite将“with”上下文管理器与 pysqlite 一起使用
【发布时间】:2019-05-30 12:43:28
【问题描述】:

我正在尝试使用 pysqlite 的“with”上下文管理器:

>>> with conn.cursor() as db:
  res = db.execute("SELECT * FROM Publishers LIMIT 5;").fetchall()

... ... Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: __enter__

我看到 __enter____exit__ 方法没有定义,所以 with 上下文管理器将不可用。

我还从 pysqlite 文档了解到 sqlite3 在连接方面有点古怪。一般来说,我更喜欢根据惯用的 python 将上下文管理器与 python DB API 一起使用。

这是否表明我/不应该/尝试重载并实现上下文管理器? sqlite3 绑定中的某些内容使这不明智或不习惯?

这是否意味着正确的使用将我的光标仅实例化一次 (db = conn.cursor()) 作为全局并在我的每个函数中调用它 (db.execute(query,params))?或者我必须在每个函数中重新实例化、调用和关闭数据库(db = conn.cursor(); db.query(query,params); db.close() 并且这样做很冗长,缺少上下文管理器?

【问题讨论】:

  • 你没有使用 stdlib 中的 sqlite 有什么原因吗?
  • 你的问题也取决于你的用例,你的过程是幂等的吗?如果不是,您可能需要一个光标实例,以便您可以回滚所有内容,反之亦然
  • @aws_apprentice,是的,我正在使用 fts5 和 json 模块,您必须自己构建。所以,我的导入最终从pysqlite3 import dbapi2 as sqlite3charlesleifer.com/blog/…

标签: python sqlite contextmanager pysqlite


【解决方案1】:

根据documentation,您使用连接作为上下文管理器(with conn as db:),而不是连接光标with conn.cursor() as db:):

import sqlite3

con = sqlite3.connect(":memory:")
con.execute("create table person (id integer primary key, firstname varchar unique)")

# Successful, con.commit() is called automatically afterwards
with con:
    con.execute("insert into person(firstname) values (?)", ("Joe",))

# con.rollback() is called after the with block finishes with an exception, the
# exception is still raised and must be caught
try:
    with con:
        con.execute("insert into person(firstname) values (?)", ("Joe",))
except sqlite3.IntegrityError:
    print "couldn't add Joe twice"

【讨论】:

    猜你喜欢
    • 2016-10-21
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    相关资源
    最近更新 更多