You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sqlmodel_update() overwrites all fields from BaseModel input, silently destroying data in PATCH endpoints #1835
When sqlmodel_update() receives a BaseModel instance, it iterates over every field and calls setattr for each one — including fields the caller never set. There is no exclude_unset parameter and no awareness of __pydantic_fields_set__.
Reproduction
classHeroUpdate(SQLModel):
name: str|None=Noneage: int|None=None@app.patch("/heroes/{hero_id}")defupdate_hero(hero_id: int, hero_update: HeroUpdate, session: Session=Depends(get_session)):
db_hero=session.get(Hero, hero_id)
db_hero.sqlmodel_update(hero_update) # Overwrites age=None even if client only sent namesession.add(db_hero)
session.commit()
Client sends {"name": "New Name"}. hero_update.age defaults to None. The method overwrites the hero's existing age with None, silently destroying data.
This works but is non-obvious. The method's type signature explicitly accepts BaseModel, implying it handles this case correctly.
Proposed Fix
Add an exclude_unset: bool = False parameter to sqlmodel_update(). When True and obj is a BaseModel, filter to only obj.__pydantic_fields_set__ before applying:
Activity