Flask SQLAlchemy执行db.session.add时报builtins.NoneType未映射错误
错误原因及修复方案
核心错误点
- 查询逻辑错误
你调用update = LeaveBalance.query.get(leave.id)时,传入的参数是leave.id(请假申请表LeaveApplication的主键ID),而query.get()是按目标表(这里是LeaveBalance假期余额表)的主键查询,两个表的主键没有关联,所以查询结果为None。后续你执行db.session.add(update)本质是往会话里添加None,自然触发NoneType属性不存在的报错。 - 修改属性逻辑错误
你写的LeaveBalance.credits = updated_leavebalance是给ORM类本身赋值类属性,没有修改你之前查询到的、对应用户对应假期类型的余额实例的属性值,完全不会生效。
异常本质解释
你遇到的UnmappedInstanceError: Class 'builtins.NoneType' is not mapped是SQLAlchemy的典型报错:session.add()方法只接受ORM映射类的实例作为参数,你传入的None不属于任何映射的ORM类,所以抛出该异常。
正确代码示例
from datetime import datetime, timedelta # 新增请假申请逻辑保持不变 leave = LeaveApplication( user_id='1', leavetype_id='1', date_created=datetime.utcnow(), date_from=datetime.today() + timedelta(days=3), date_to=datetime.today() + timedelta(days=5), description='testing' ) db.session.add(leave) db.session.commit() # 计算请假天数:如果需要包含请假首尾日,可在后面+1(比如3号到5号共3天,原差值是2天) leave_days = (leave.date_to - leave.date_from).days # 直接修改之前查询到的目标余额实例即可 current_leavebalance = LeaveBalance.query.filter_by(user_id='1', leavetype_id=leave.leavetype_id).first() current_leavebalance.credits -= leave_days # 已经在会话中的ORM实例修改属性后,直接commit即可,不需要手动add db.session.commit()
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

