Flask+MariaDB应用PUT接口更新失败及one()函数异常排查
Flask + MariaDB CRUD 应用更新功能问题解决
问题1:PUT请求触发SQL语法错误,字典解包无效
- 场景:POST接口用
**字典解包解决过类似语法问题,但PUT请求(请求体{"description": "new test"})仍报错。 - 原因:POST通常用于创建完整记录,字段固定;PUT是部分字段更新,直接解包会导致UPDATE语句的SET子句语法错误(比如字段数量不匹配、多余符号)。
- 解决:
- 原生SQL动态生成SET子句(需过滤字段防注入):
data = request.get_json() # 替换为你的表允许更新的字段 allowed_fields = ["description", "title"] valid_data = {k: v for k, v in data.items() if k in allowed_fields} if not valid_data: return jsonify({"error": "No valid fields to update"}), 400 # 用反引号包裹字段避免关键字冲突 set_clause = ", ".join([f"`{k}` = %s" for k in valid_data.keys()]) values = list(valid_data.values()) values.append(id) # id为更新目标的主键值 cursor.execute(f"UPDATE your_table SET {set_clause} WHERE id = %s", values) conn.commit() - SQLAlchemy ORM方式(更安全简洁):
data = request.get_json() obj = db.session.get(YourModel, id) if not obj: return jsonify({"error": "Record not found"}), 404 allowed_fields = ["description", "title"] for k, v in data.items(): if k in allowed_fields: setattr(obj, k, v) db.session.commit()
- 原生SQL动态生成SET子句(需过滤字段防注入):
问题2:更新功能正常,但query.one()报错(数据库存在对应行)
- 原因:
- 事务未提交:更新后未执行
db.session.commit()(ORM)或conn.commit()(原生SQL),查询读取的是session缓存的旧数据。 - 查询条件错误:主键参数传递错误,或字段名与数据库表不匹配。
- SQLAlchemy缓存问题:session内的对象未刷新,查询返回缓存的过期数据。
- 事务未提交:更新后未执行
- 解决:
- 确保更新后提交事务:
db.session.query(YourModel).filter_by(id=id).update(valid_data) db.session.commit() # 必须提交事务 result = db.session.query(YourModel).filter_by(id=id).one() - 刷新对象或强制从数据库查询:
obj = db.session.get(YourModel, id) setattr(obj, "description", data["description"]) db.session.commit() db.session.refresh(obj) # 刷新对象到最新状态 # 或直接发起新查询 result = db.session.query(YourModel).filter_by(id=id).one() - 检查查询条件:确认
id参数是否正确传递,字段名与数据库表字段完全一致(注意大小写敏感)。
- 确保更新后提交事务:
内容的提问来源于stack exchange,提问作者Alucard
相关产品推荐
相关产品推荐

