Flask+SQLAlchemy开发足球运动员REST API仅POST生效 PUT/DELETE无效果如何解决
问题原因
你的代码存在两个核心问题导致PUT、DELETE请求无效:
- 路由参数类型不匹配
Flask路由默认接收的<id>参数是字符串类型,但你数据库中Player表的id字段是整数类型,用字符串值过滤整数字段永远匹配不到任何记录。你可以从日志中看到,PUT请求传参是'9'(带引号的字符串),DELETE请求传参是'6',自然无法匹配到你POST创建的id为整数9的球员。 - 异常捕获逻辑不合理
你用了裸except:语句,会吞掉所有运行时异常(比如匹配不到球员时,给None对象赋值last_modified的AttributeError),你无法感知实际错误;且Query.update()、Query.delete()方法匹配不到行时本身不会抛出异常,只会返回0的匹配行数,你没有做判断就直接返回成功,导致你误以为请求执行成功。
修复方案
1. 修正路由参数类型
将PUT、DELETE路由的<id>参数指定为整数类型,确保传入的id和数据库字段类型一致:
# PUT路由 @app.route('/players/<int:id>', methods=['PUT']) def update_player(id): # 逻辑省略 # DELETE路由 @app.route('/players/<int:id>', methods=["DELETE"]) def delete_player(id): # 逻辑省略
2. 优化业务逻辑,移除裸异常捕获
修改后的PUT接口:
@app.route('/players/<int:id>', methods=['PUT']) def update_player(id): # 先校验请求格式 if not request.is_json: return bad_request("请求必须为JSON格式") # 先判断球员是否存在 player = Player.query.get(id) if not player: return not_found("Player does not exist") try: data = request.get_json() # 逐字段更新,避免非法字段传入、禁止修改id for field, value in data.items(): if hasattr(player, field) and field != 'id': setattr(player, field, value) player.last_modified = datetime.datetime.now() db.session.commit() return jsonify({'player': player.serialize}), 200 except TypeError: db.session.rollback() return bad_request("Invalid input data.")
修改后的DELETE接口:
@app.route('/players/<int:id>', methods=["DELETE"]) def delete_player(id): player = Player.query.get(id) if not player: return not_found("Player does not exist.") try: db.session.delete(player) db.session.commit() return '', 204 except Exception as e: db.session.rollback() return bad_request(f"删除失败:{str(e)}")
额外优化建议
- 不要把
datetime对象转成字符串存储,直接将last_modified字段设为DateTime类型,直接存原生datetime对象,SQLAlchemy会自动处理格式转换 - 接口返回码要符合REST规范:PUT成功返回200,DELETE成功返回204,不要都用201
- 所有数据库操作出错时都要调用
db.session.rollback()回滚会话,避免脏数据影响后续请求
内容的提问来源于stack exchange,提问作者studentofml
相关产品推荐
相关产品推荐

