在pysqlite中使用“ with” contextmanager

时间:2019-01-03 22:16:11

标签: python sqlite contextmanager pysqlite

我正在尝试通过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 contextmanager将不可用。

我也从pysqlite文档中了解到sqlite3在连接方面有点古怪。通常,我更喜欢将上下文管理器与每个惯用的python配合使用python DB API。

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

这是否意味着正确的用法将实例化为全局一次仅将光标(db = conn.cursor())实例化一次(db.execute(query,params))?还是我必须在每个函数(db = conn.cursor(); db.query(query,params); db.close()中重新实例化,调用并关闭db,并且在缺少上下文管理器的情况下进行冗长的操作?

1 个答案:

答案 0 :(得分: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"