Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pydantic input model for partial updates

I am using Pydantic to validate data inputs in a server. Pydantic models:

  • User: for common fields
  • UserIn: user input data to create new account
  • UserInDB: to hash password and include extra fields like created_at
  • UserOut: to output created/updated user data

Now how can I utilize the model UserIn for user account partial updates? so that None fields are excluded. Or do I have to rewrite it again and make every field optional?

class User(BaseModel):

    name_first :          str = Field(...)
    name_last :           Optional[str] = None
    mobile :              int = Field(..., description="It has to be 8 digits and starts with either 9 or 7", example="99009900")
    
    email :               Optional[EmailStr] = None
    
    gender:               Literal['m', 'f'] = Field(..., example="m")
    birth_date:           datetime.date
    preferred_language :  Literal['ar', 'en'] = Field(..., example="ar")
    newsletter :          bool = Field(...)


    @validator('mobile')
    def number_has_to_start_with_9_or_7(cls, v):
        if str(v)[:1] !="9" and str(v)[:1] !="7":
            raise ValueError('Mobile number must start with 9 or 7')
        if len(str(v)) !=8:
            raise ValueError('Mobile number must be 8 digits')
        return v


class UserIn(User):
    password: str = Field(...)

class UserInDB(UserIn):
    mobile_otp:           int = Field(...)
    bitrole:              int = Field(...)
    created_at:           datetime.datetime
    updated_at:           datetime.datetime

class UserOut(User):
    id:                   int
    mobile_otp:           int
    bitrole:              int
    mobile_confirmed :    bool
    email_confirmed :     bool
    disabled :            bool
    created_at:           datetime.datetime
    updated_at:           datetime.datetime

    class Config:
        orm_mode = True
like image 705
Sami Al-Subhi Avatar asked Mar 14 '26 11:03

Sami Al-Subhi


1 Answers

Unfortunately this is a problem that has been already faced by quite a lot of people (me included).

There is no simple way of handling it out of the box and as far as I know.

Here are some solutions proposed to bypass the problem, although not completely, on github

https://github.com/samuelcolvin/pydantic/issues/990#issuecomment-645961530

MY SOLUTION

I use pydantic with fastapi and partial updates of resources are quite common. Due to the limitation of pydantic I ask the user to resubmit all the values, filling correctly the pydantic model and then update all the fields that can be updated.

It's not ideal, I know, but it seems to work

UPDATE

I've found another possible solution. Basically, retrieve the old data, update it, and write the updated data (much better than my solution).

See fastapi docs https://fastapi.tiangolo.com/tutorial/body-updates/#partial-updates-with-patch

Warning: Partial updates with nested object are currently not implemented in pydantic. See https://github.com/pydantic/pydantic/issues/4177

like image 69
lsabi Avatar answered Mar 15 '26 23:03

lsabi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!