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

FastAPI对接SQL Server执行PATCH/PUT报错无法更新identity列如何解决

FastAPI + SQL Server PATCH/PUT更新报错解决方案

报错原因

你遇到的报错是SQL Server的原生限制:

(pyodbc.ProgrammingError) ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Cannot update identity column 'id'.")

identity属性修饰的列是SQL Server的自增主键,数据库层面禁止手动修改该字段的值,报错是因为你的更新逻辑把id字段放到了UPDATE语句的SET子句中。

修复方案

  • 方案1:单独定义更新专用的Pydantic模型
    不要复用包含id字段的创建/返回模型作为PATCH/PUT的请求体模型,单独定义不含主键、所有字段可选的更新模型,适配部分更新的需求:
from pydantic import BaseModel
from typing import Optional

# 示例:更新模型不包含id字段,所有字段可选
class ItemUpdate(BaseModel):
    name: Optional[str] = None
    price: Optional[float] = None
    description: Optional[str] = None

接口路径函数中使用该模型,更新时仅取用户传入的非空字段赋值:

@app.patch("/items/{item_id}")
def update_item(item_id: int, update_data: ItemUpdate, db: Session = Depends(get_db)):
    # 按路径参数的id查询待更新记录
    target_item = db.query(Item).filter(Item.id == item_id).first()
    if not target_item:
        return {"code": 404, "msg": "目标记录不存在"}
    # 仅更新用户传入的字段,exclude_unset会过滤掉未赋值的字段
    for field, value in update_data.dict(exclude_unset=True).items():
        setattr(target_item, field, value)
    db.commit()
    db.refresh(target_item)
    return target_item
  • 方案2:ORM更新时显式排除id字段
    如果你直接使用ORM的update方法批量更新,在转参时显式排除id字段即可:
# 错误写法:会把id字段带入更新逻辑触发报错
db.query(Item).filter(Item.id == item_id).update(update_data.dict())

# 正确写法:排除id字段
db.query(Item).filter(Item.id == item_id).update(update_data.dict(exclude={"id"}))
  • 方案3:手写SQL时检查UPDATE语句结构
    如果是手写原生SQL执行更新,确保id仅出现在WHERE条件中作为筛选参数,不要放到SET子句里:
-- 错误写法
UPDATE item SET id = ?, name = ? WHERE id = ?

-- 正确写法
UPDATE item SET name = ?, price = ? WHERE id = ?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 12:48:01