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

Flask API PUT方法更新isdeleted字段后未持久化到数据库问题

问题根因

接口返回值显示字段修改成功但数据库未持久化,是几个Flask-SQLAlchemy的典型使用错误导致的:

  • 代码逻辑缩进有缺陷:db.session.commit()写在了if 'id' in request.headers判断块外部,当请求头缺失id时不仅会触发user未定义的报错,当会话中没有待提交的变更时,commit会空跑不执行任何写入。
  • 主键类型不匹配:请求头中取出的id是字符串类型,如果Users表的主键id是整型,部分SQLAlchemy版本和数据库驱动适配场景下,query.get(字符串id)查出的实体不会被正确注册到当前会话的持久化上下文。你只是在内存里修改了对象属性,所以接口返回能看到isdeleted=True,但会话追踪不到这个对象的变更,commit阶段根本不会生成对应的UPDATE SQL,自然不会写入数据库。
  • 额外排查项:检查@token_required装饰器的实现,如果装饰器内部完成数据库查询后触发了db.session.close()或者rollback(),会导致后续查出的user对象处于游离状态,修改无法被会话捕获。
修复方案
  1. 对传入的id做类型转换,和数据库主键类型保持一致
  2. 调整代码结构,把参数校验、用户查询、字段修改、事务提交的逻辑全部收敛到参数合法的分支内,增加空值判断避免查无数据时报错
  3. 修改字段后显式把对象add到当前会话,强制会话追踪对象变更,再执行提交

修复后的代码如下:

@app.route('/User/Delete', methods=['PUT'])
@token_required
def delete_users(current_user):
    # 先做参数校验,参数不合法直接返回错误
    if 'id' not in request.headers:
        return {"msg": "缺少必要参数用户id"}, 400
    # 类型转换,和模型主键类型匹配,示例主键为整型
    try:
        user_id = int(request.headers['id'])
    except ValueError:
        return {"msg": "用户id格式非法"}, 400
    
    user = Users.query.get(user_id)
    if not user:
        return {"msg": "指定用户不存在"}, 404
    
    user.isdeleted = True
    # 显式加入会话,避免游离对象变更不被追踪
    db.session.add(user)
    db.session.commit()
    
    return user_schema.jsonify(user)
验证方式

可以打开SQLAlchemy的SQL执行日志,确认接口调用时确实向数据库发送了更新语句:

# 项目配置中添加该参数即可打印所有执行的SQL
app.config["SQLALCHEMY_ECHO"] = True

正常触发逻辑时控制台会输出类似UPDATE users SET isdeleted=1 WHERE users.id = %s的日志,说明更新语句已经成功执行,后续调用查询接口就能拿到正确的软删除状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:51:07