mch*_*gun 4 python sqlite sqlalchemy
我正在select()从SQLite数据库做一个,然后是insert():
engine = create_engine('sqlite:///testdb.db')
metadata = MetaData(bind=engine)
test = Table('test', metadata, autoload=True)
# Select all from pending_data
sel = select([test])
res = engine.execute(sel)
print res
# do an insert into pending_data
test.insert()\
.values(info='blah')\
.execute()
Run Code Online (Sandbox Code Playgroud)
当我的代码执行插入行时,我收到此错误:
sqlalchemy.exc.ResourceClosedError: This Connection is closed
Run Code Online (Sandbox Code Playgroud)
但是,如果我将res转换为如下列表:
res = list(engine.execute(sel))
Run Code Online (Sandbox Code Playgroud)
我的代码运行正常.这里发生了什么?
Ant*_*ala 11
SQLAlchemy有两个必须要注意的概念:连接和引擎.引擎可以支持许多同时连接.在您的示例中,您将表绑定到引擎.现在,无论何时调用,都会.execute为您执行的每个查询创建一个新连接.但sqlite3只允许1个同时"连接".
解决此问题的最佳方法是创建连接并显式使用它,而不是自动创建的引擎连接; 并使用与with语句的连接,这确保连接将在块的末尾关闭:
engine = create_engine('sqlite:///testdb.db')
metadata = MetaData(bind=engine)
test = Table('test', metadata, autoload=True)
with engine.connect() as connection:
# Select all from pending_data
sel = select([test])
res = connection.execute(sel)
# do an insert into pending_data
connection.execute(test.insert().values(info='blah'))
Run Code Online (Sandbox Code Playgroud)
要理解这种行为,会发生错误,因为您在隐式创建和保持的集合中持有活动游标(这由res变量引用;直到您使用它,或关闭它,或删除对它的引用,游标,因此连接将处于活动状态,数据库将被锁定).
当你执行时list(res),你正在消耗光标并被SQLAlchemy关闭; 如果结果的引用计数将降至0,则会发生相同的情况.
您还可以尝试以下方法来查看要点,它们可以按预期工作:
res = engine.execute(sel)
print(res)
res.close() # close explicitly
Run Code Online (Sandbox Code Playgroud)
要么
res = engine.execute(sel)
print(res)
del res # drop the only reference to res
Run Code Online (Sandbox Code Playgroud)
因此,始终完全使用ResultProxy或显式关闭它,或者在完成后删除对它的引用.
如果重用相同的连接,这不是问题; 只有当你创建一个sqlite3数据库的新连接时(postgresql,mysql,oracle等处理这个也没关系).
| 归档时间: |
|
| 查看次数: |
7048 次 |
| 最近记录: |