我正在尝试通过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,并且在缺少上下文管理器的情况下进行冗长的操作?
答案 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"