【问题标题】:FastApi: 422 Unprocessable EntityFastApi:422 无法处理的实体
【发布时间】:2022-01-25 15:51:37
【问题描述】:

我在尝试接受迂腐模型时遇到此错误。经过一段时间的调试,我认为问题在于接受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

【问题讨论】:

  • FastAPIs 422 响应的正文包含一条错误消息,告诉您请求的哪一部分与预期格式不匹配。

标签: python fastapi pydantic http-status-code-422


【解决方案1】:

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

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

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

【讨论】:

  • 我已经编辑了我的问题并添加了客户的请求正文,这是 Swagger UI 推荐的内容,但它不起作用。
【解决方案2】:

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

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

【讨论】:

  • 怎么不是按照CodeCreate?
  • 这个请求正文是 Swagger UI 建议的?
  • 你确定可以互相继承pydantic模型吗?
  • 是的,它已记录在案。这里fastapi.tiangolo.com/tutorial/sql-databases/…
  • 好的,知道了!很高兴你解决了这个问题。
【解决方案3】:

调试了半天找到了解决办法。

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

在我的例子中,我必须创建另一个类来扩展 CodeCreate 类,将 ORM 配置添加到该类并使用 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

发布请求

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-15
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多