FastApi:422 无法处理的实体

ASA*_*EED 1 python http-status-code-422 pydantic fastapi

我在尝试接受迂腐模型时遇到此错误。经过一段时间的调试后,我相信问题出在接受上CodeCreate

悬垂模型

class BaseCode(BaseModel):
    index: Optional[int] = Field(None)
    email: EmailStr
    gen_time: datetime
    expire_time: datetime


class CodeCreate(BaseCode):
    code: int
    used_time: Optional[datetime] = Field(None)

    class Config:
        orm_mode = True

class Message(BaseModel):
    message: str
Run Code Online (Sandbox Code Playgroud)

代码 ORM

class Code(Base):
    __tablename__ = 'code'

    index = Column(Integer, primary_key=True, autoincrement=True)
    code = Column(Integer)
    email = Column(String, ForeignKey('user.email'))
    gen_time = Column(DateTime)
    expire_time = Column(DateTime)
    used_time = Column(DateTime, nullable=True)
Run Code Online (Sandbox Code Playgroud)

处理程序

@app.post('/verify-code', response_model=schemas.Message, responses={404: {"model": schemas.Message}, 406: {"model": schemas.Message}})
async def verify_code(code: schemas.CodeCreate, response: Response, device_name: str = Body(..., embed=True), db=Depends(get_db)):

    result = crud.verify_and_insert_code(db=db, code=code)
    if result == 'matched':
        response.status_code = status.HTTP_202_ACCEPTED
        return crud.start_new_session(db=db, session=schemas.Session(session_id='1234', start_time=datetime.now(), email=code.email, device_name=device_name))
    elif result == 'not-matched':
        response.status_code = status.HTTP_200_OK
    elif result == 'expire':
        response.status_code = status.HTTP_406_NOT_ACCEPTABLE
    elif result == 'invalid':
        response.status_code = status.HTTP_404_NOT_FOUND

    return schemas.Message(message="Item not found")
Run Code Online (Sandbox Code Playgroud)

客户端请求正文

{
  "code": {
    "index": 0,
    "email": "user@example.com",
    "gen_time": "2022-01-24T16:38:12.612Z",
    "expire_time": "2022-01-24T16:38:12.612Z",
    "code": 0,
    "used_time": "2022-01-24T16:38:12.612Z"
  },
  "device_name": "string"
}
Run Code Online (Sandbox Code Playgroud)

422 的响应正文

{
  "detail": [
    {
      "loc": [
        "body",
        "code",
        "email"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    },
    {
      "loc": [
        "body",
        "code",
        "gen_time"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    },
    {
      "loc": [
        "body",
        "code",
        "expire_time"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    },
    {
      "loc": [
        "body",
        "code",
        "code"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

临时解决方案

从 Pydantic 模型中删除此 ORM 确认代码可以解决该问题。CodeCreate我相信pydantic 模型和ORM 模型之间可能存在冲突Code,但我不知道如何解决它。

class Config:
    orm_mode = True
Run Code Online (Sandbox Code Playgroud)

小智 5

422 Unprocessable Entity由于ContentType不正确而导致的错误。FastAPI/Pydantic 需要ContentType = application/json解析请求正文。

您确定您的 POST 请求的 ContentType 标头是 application/json吗?

如果没有就添加吧!