【问题标题】:SQLAlchemy Session.commit() hangsSQLAlchemy Session.commit() 挂起
【发布时间】:2019-12-18 03:29:27
【问题描述】:

我正在使用来自 SQLAlchemy(到 MySQL)的scoped_sessions,并在 tornado 的线程池中运行 SQL 提交。在我的单元测试中,第一次Session.commit() 通过但第二次Session.commit() 挂起。我在第一次提交后正确关闭了会话。我启用了 SQLAlchemy 日志记录,我可以看到在 INSERT INTO ... 第二次提交之后没有发出任何内容。

【问题讨论】:

  • 更多信息:我尝试提交的对象是声明性基本模型对象,它们从 mysql 中获得一个 id 作为自动增量 id。上面的提交实际上是将该对象插入到数据库中。

标签: mysql sqlalchemy tornado


【解决方案1】:

今天早些时候遇到同样的问题(稍后提交)让我想到了这个问题。通过确保只有一个会话到位,我设法解决了这个问题。

在我的情况下,我正在为每个测试运行带有会话测试的集成测试,并以described in docs 的形式回滚。我已经将所有数据库内容包装在负责测试设置的 DatabaseService 类中(派生的 TestDatabaseClass 在 ctor 中进行会话设置)。

问题是我成功地初始化了 DatabaseService 实例(使用测试设置)两次,并在后来创建的嵌套会话的提交中遇到了挂起(或在显式刷新调用中)。所以确保只有一个 DatabaseService 存在并且所有数据库查询都通过一个会话确实为我解决了这个问题。

【讨论】:

    【解决方案2】:

    您的会话初始化是什么样的?你不使用autoflush吗?提交后尝试调用session.flush()

    【讨论】:

    • 我的初始化看起来像:scoped_session(sessionmaker())。我尝试在提交后添加 flush() .. 在第二次提交时仍然卡住。这只是我正在运行的两个测试,所以我怀疑我正在用完池中的所有连接。
    • 测试代码的一部分是否创建了原始会话?是否有一个 rc 文件可以让您跳过 bind=engine 参数?来自文档的示例:>>> from sqlalchemy.orm import scoped_session >>> from sqlalchemy.orm import sessionmaker >>> session_factory = sessionmaker(bind=some_engine) >>> Session = scoped_session(session_factory)
    • 谢谢克里斯。问题是我在两个测试之间有一个待处理的交易。这导致下一次提交没有发生。
    【解决方案3】:

    问题是我在两个测试之间有一个待处理的事务。这导致下一次提交没有发生。

    【讨论】:

    • 您如何诊断出您有待处理的交易?你是怎么解决的?
    • 我的同样问题。
    猜你喜欢
    • 2020-12-17
    • 1970-01-01
    • 2021-08-20
    • 2014-04-16
    • 2017-09-21
    • 2015-07-17
    • 2015-10-19
    • 2013-12-10
    • 1970-01-01
    相关资源
    最近更新 更多