Pydantic输入模型,用于部分更新

问题描述

我正在使用Pydantic来验证服务器中的数据输入。金字塔模型:

现在如何使用模型UserIn进行用户帐户的部分更新?这样就排除了None字段。还是我必须再次重写它并使每个字段都可选?

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

解决方法

不幸的是,这是很多人(包括我在内)已经面临的问题。

据我所知,没有开箱即用的简单处理方法。

在github上提出了一些解决该问题的方法,尽管不是完全解决问题

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

我的解决方案

我将pydantic与fastapi一起使用,部分资源更新非常普遍。由于pydantic的限制,我要求用户重新提交所有值,正确填写pydantic模型,然后更新所有可以更新的字段。

我知道这不是理想的方法,但是似乎可行

更新

我找到了另一种可能的解决方案。基本上,检索旧数据,对其进行更新并写入更新后的数据(比我的解决方案要好得多)。

请参阅fastapi文档https://fastapi.tiangolo.com/tutorial/body-updates/#partial-updates-with-patch