You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Pytest在SQLAlchemy提交后丢失内存对象?调试可过正常运行失败

问题描述

编写测试用例验证从数据库获取对象的函数,断言取回的对象与此前写入数据库的本地创建对象相等,但测试正常运行时始终失败,仅在调试模式下保持变量面板打开查看类属性时才能通过。

测试代码如下:

def test_get_dupe_check_and_rules(engine):
    test_lead = Lead(id='test_lead')
    test_dupe_rule = DupeRule(hours=24,
                              found_count=1,
                              dupe_limit='1',
                              result='failed')
    test_dupe_check = DupeCheck(lead=test_lead, result='failed')
    test_dupe_check.dupe_rules.append(test_dupe_rule)

    with Session(engine) as db_session:
        db_session.add(test_lead)
        db_session.add(test_dupe_check)
        db_session.commit()

    check = get_dupe_check_and_rules(test_lead, engine)

    assert check == test_dupe_check

现象:执行db_session.commit()后,若未打开变量面板,本地创建对象的属性会被替换为懒加载错误信息:Parent instance <DupeCheck at 0x101c889c0> is not bound to a Session; lazy load operation of attribute 'lead' cannot proceed,原本仅插入数据库未查询的test_dupe_check变为空DupeCheck实例,导致断言失败。

原因分析
  • Session关闭后对象脱管:with代码块结束后,db_session会自动关闭,此前绑定到该Session的test_lead、test_dupe_check等对象会进入脱管状态,不再和任何数据库会话关联。
  • 懒加载触发时机差异:
    • 调试时打开变量面板,会主动触发对象所有属性的读取(比如展示test_dupe_check.lead、test_dupe_check.dupe_rules),此时Session尚未关闭,懒加载会正常执行,把关联属性加载到本地对象中,对象保持完整状态。
    • 正常运行时,with块结束Session关闭后,代码后续访问脱管对象的懒加载属性(比如断言相等时对比关联属性),会触发懒加载失败——因为没有Session支持数据库查询,导致属性无法正常读取,甚至对象状态异常。
  • 对象相等性对比的问题:SQLAlchemy对象的相等性默认会对比所有属性(或依赖Session状态),脱管对象因懒加载失败导致属性缺失或报错,无法和从新Session中查询出来的check对象匹配,最终断言失败。

内容的提问来源于stack exchange,提问作者doublea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 14:45:17