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

使用PyMongo更新嵌套字典时遭遇ReferenceError问题求解

解决PyMongo/MongoEngine更新嵌套字典时的ReferenceError问题

错误原因

你遇到的ReferenceError: weakly-referenced object no longer exists,是因为直接从MongoEngine文档实例中取出的spare_2字典是对原文档对象的弱引用。当原文档实例被Python垃圾回收机制回收后,这个引用就失效了,后续尝试用它更新数据库自然会报错。

解决方案

方案1:深拷贝字段内容后修改

先把spare_2的内容深拷贝出来,脱离原文档实例的引用,修改后再更新:

from copy import deepcopy

# 获取目标用户文档
user = User.objects.filter(username=current_user).first()
if not user:
    # 处理用户不存在的情况
    pass

# 深拷贝spare_2,避免引用原文档对象
my_dict = deepcopy(user.spare_2)
# 添加或更新quiz_id对应的内容
my_dict[quiz_id] = {
    'question1': 9, 'question2': 9, 'question3': 9,
    'question4': 9, 'question5': 9, 'question6': 9,
    'question7': 9, 'question8': 9, 'question9': 9, 'question10': 9
}
# 更新数据库
user.update(spare_2=my_dict)

方案2:使用原子更新(推荐)

直接用MongoEngine的原子更新操作,不需要取出整个字典,既避免引用问题,又能保证并发场景下的数据安全:

# 方式1:MongoEngine风格的嵌套更新
User.objects(username=current_user).update_one(
    set__spare_2__{quiz_id}={
        'question1': 9, 'question2': 9, 'question3': 9,
        'question4': 9, 'question5': 9, 'question6': 9,
        'question7': 9, 'question8': 9, 'question9': 9, 'question10': 9
    }
)

# 方式2:原生MongoDB操作符风格
User.objects(username=current_user).update_one(
    {"$set": {f"spare_2.{quiz_id}": {
        'question1': 9, 'question2': 9, 'question3': 9,
        'question4': 9, 'question5': 9, 'question6': 9,
        'question7': 9, 'question8': 9, 'question9': 9, 'question10': 9
    }}}
)

注意:如果spare_2原本不存在,原子更新会自动创建该字段;如果quiz_id对应的键已存在,会直接覆盖原有值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:25:22