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