使用 SQLAlchemy 和 sqlite 的嵌套事务
我正在使用 SQLAlchemy(和 Elixir)用 Python 编写一个应用程序,并以 SQLite 作为数据库后端。我使用代码 session.begin_transaction()
启动一个新事务,但是当我调用 session.rollback()
时,我收到以下错误:
sqlalchemy.exceptions.OperationalError: (OperationalError) no such savepoint: sa_savepoint_1 u'ROLLBACK TO SAVEPOINT sa_savepoint_1' []
我也收到类似的错误调用session.commit()
。据我所知,sqlite 支持 SAVEPOINTS (http://www.sqlite.org/lang_savepoint.html)。
如何让嵌套事务发挥作用?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我在 Windows 上使用 Python 3 使用嵌套事务时遇到了这个问题。我使用的是 SQLite 版本 3.8.11,因此应该支持
SAVEPOINT
。显然,安装 pysqlite 对我来说不是一个选择,因为它不支持 Python 3。经过几个小时的头撞桌子后,我在文档中发现了这一部分:
http://docs.sqlalchemy.org/en/latest/dialects/sqlite.html#serialized-隔离-保存点-事务-ddl
添加上面的听众完全解决了我的问题!
我已经发布了一个完整的工作示例作为要点:
https://gist.github.com/snorfalorpagus/c48770e7d1fcb9438830304c4cca24b9
我还发现记录 SQL 语句很有帮助(这在上面的示例中使用):
调试(显示)由 SQLAlchemy 发送到数据库的 SQL 命令
I've run into this issue using nested transactions, using Python 3 on Windows. I'm using SQLite version 3.8.11, so
SAVEPOINT
should be supported. Apparently installing pysqlite isn't an option for me as it doesn't support Python 3.After hours of banging my head against the desk I came across this section in the documentation:
http://docs.sqlalchemy.org/en/latest/dialects/sqlite.html#serializable-isolation-savepoints-transactional-ddl
Adding the listeners above completely resolved the issue for me!
I've published a full working example as a gist:
https://gist.github.com/snorfalorpagus/c48770e7d1fcb9438830304c4cca24b9
I also found logging the SQL statements helpful (this is used in the above example):
Debugging (displaying) SQL command sent to the db by SQLAlchemy
尽管 sqlite 似乎确实支持通过 SAVEPOINT 进行嵌套事务,但仅从 2009 年 1 月 12 日发布的版本 3.6.8 开始。 Python,至少到 v2.6,使用早期版本:
我相信你可以安装 PySqlite你自己,最新的似乎支持v3.6.12。我不能肯定地说这会解决你的问题,但我相信答案解释了为什么它现在不适合你。
Although sqlite does appear to support nested transactions via SAVEPOINT, it's only as of version 3.6.8, released 2009 Jan 12. Python, at least up to v2.6, uses earlier versions:
I believe you can install PySqlite yourself and the latest appears to support v3.6.12. I can't say for sure this will solve your problem though, but I believe the answer explains why it's not working for you now.
SQLAlchemy 使用 pysqlite 与 SQLite 数据库交互,如果我没有记错的话,pysqlite 默认情况下会包装您在事务中发送的任何查询。
答案可能在于连接时正确设置隔离级别。
此处有一些相关讨论
SQLAlchemy uses pysqlite to interact with an SQLite database, if I'm not mistaken pysqlite will by default wrap up any query you send it in a transaction.
The answer might lie in correctly setting the isolation level when you connect.
Some discussion about that over here