FastApi:422 无法处理的实体

FastApi: 422 Unprocessable Entity

我在尝试接受迂腐模型时遇到此错误。调试了一段时间后,我认为问题出在接受 CodeCreate

Pydantic 模型

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

代码 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)

处​​理程序

@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")

来自客户端的请求正文

{
  "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"
}

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"
    }
  ]
}

临时解决方案

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

class Config:
    orm_mode = True

根据 MDN here, a 422 Unprocessable Entity表示无法处理请求的信息。

这种情况下,最有可能的问题是发送的POST请求的数据与Pydantic模型不匹配。

确保发送的数据格式正确。

正如 Brian Law 上面所说,您的请求正文是 Code 的形式,这不是 pydantic 模型,而是数据库模型。

当您发送 POST 请求时,正文应与 CodeCreate 匹配,而不是 Code

调试了半天找到解决方法

ORM 配置的迂腐模型不能用于接收来自客户端的请求。

在我的例子中,我必须创建另一个 class 来扩展 CodeCreate class 添加 ORM 配置到那个 class 并使用 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 Code(CodeCreate):

    class Config:
            orm_mode = True

Post请求

@app.post('/verify-code')
async def verify_code(code: schemas.CodeCreate):
    return 'success'