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

FastAPI+SQLAlchemy ORM更新报错:TypeError: Query.update()参数异常

解决FastAPI中SQLAlchemy ORM更新记录的TypeError问题

错误原因

你遇到的TypeError是因为SQLAlchemy的Query.update()方法要求传入字典格式的参数,而非直接传递关键字参数(如title=request.title);另外db.refresh()只能作用于ORM模型实例,不能用于Query对象。

正确实现方式

以下提供两种常用的正确更新方案:

方案1:使用Query.update()(批量更新风格)

from fastapi import HTTPException, status, Depends
from sqlalchemy.orm import Session
import models
from schemas import TodoRequest, TodoResponse

@app.put('/todos/{id}', status_code=status.HTTP_202_ACCEPTED, response_model=TodoResponse)
def update_todo(id: int, request: TodoRequest, db: Session = Depends(get_db)):
    todo_query = db.query(models.Todo).filter(models.Todo.id == id)
    todo = todo_query.first()
    
    if not todo:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"todo with id {id} not found.")

    # 将Pydantic模型转为字典,exclude_unset=True只更新请求中提供的字段
    update_data = request.dict(exclude_unset=True)
    todo_query.update(update_data)
    db.commit()
    
    # 刷新实例获取最新数据库数据
    db.refresh(todo)
    return todo

方案2:直接修改ORM实例属性(直观ORM风格)

from fastapi import HTTPException, status, Depends
from sqlalchemy.orm import Session
import models
from schemas import TodoRequest, TodoResponse

@app.put('/todos/{id}', status_code=status.HTTP_202_ACCEPTED, response_model=TodoResponse)
def update_todo(id: int, request: TodoRequest, db: Session = Depends(get_db)):
    todo = db.query(models.Todo).filter(models.Todo.id == id).first()
    
    if not todo:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"todo with id {id} not found.")

    # 批量赋值,只更新请求中传入的字段
    for key, value in request.dict(exclude_unset=True).items():
        setattr(todo, key, value)
    
    # 也可以手动逐个赋值(适合字段少的场景)
    # todo.title = request.title
    # todo.completed = request.completed
    
    db.commit()
    db.refresh(todo)
    return todo

关键注意事项

  • 使用request.dict(exclude_unset=True)可以避免覆盖未在请求中传入的字段(比如请求只传了title,就不会修改completed的现有值)
  • 必须先通过first()获取模型实例,才能使用db.refresh()刷新数据
  • 不能直接将Pydantic模型对象传给update(),必须转为字典格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:35:10