这是我的三个 Pydantic 模型的定义:
class SplitType(str, enum.Enum):
AUTO = "auto"
CUSTOM = "custom"
class DocumentConfigBase(BaseModel):
'''
document config detail
'''
model_config = ConfigDict(use_enum_values=True)
mode: Optional[SplitType] = Field(
default=SplitType.AUTO, validate_default=True)
chunk_size: Optional[str] = "800"
identifier: Optional[str]
text_preprocessing_rules: Dict[str, Any]
class DocumentConfigCreate(BaseModel):
'''
document config create
'''
knowledge_id: int
config: DocumentConfigBase
class SheetConfigCreate(BaseModel):
'''
need to update
'''
knowledge_id: int
pass
class ImageConfigCreate(BaseModel):
'''
need to update
'''
knowledge_id: int
pass
在第一个模型中,我将
mode
字段定义为枚举类型。然后我写了 Router 代码。
@router.post("/config", response_model=KnowledgeConfigModel)
def create_knowledge_config(user_id: Annotated[int, Body()], config_type: Annotated[KnowledgeType, Body()], knowledge_config: Union[DocumentConfigCreate, SheetConfigCreate, ImageConfigCreate], session: Session = Depends(get_db)):
print('knowledge_config', knowledge_config)
try:
knowledge_model = KnowledgeConfigService.create(
operator=user_id, config_type=config_type,
knowledge_config=knowledge_config, session=session)
print('knowledge_model', knowledge_model)
if knowledge_model is None:
raise HTTPException(
status_code=404, detail="Config create failed")
return knowledge_model
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) from e
我在knowledge_config字段中使用了Union类型,但是当我使用以下参数请求此API时,出现错误:“detail”:“'config'”。
{
"user_id": 0,
"config_type": "document",
"knowledge_config": {
"knowledge_id": 1,
"config": {
"mode": "auto",
"chunk_size": "1000",
"identifier": "string",
"text_preprocessing_rules": {}
}
}
}
并且代码中的打印语句(
print('knowledge_config', knowledge_config)
)输出knowledge_config knowledge_id=1
。剩下的参数好像都丢了。
mode
字段自动设置为“auto”。knowledge_config: DocumentConfigCreate
时,没有错误。我获取了传递的所有参数,并且 mode
字段也自动设置为“auto”。因此,我相信我的参数没有错误;问题可能在于我使用了 Union 类型,导致 FastAPI 解析失败。
我是Python新手,请帮我解决这个问题,非常感谢!
当您使用 Union 定义输入参数时,FastAPI 应在验证阶段选择正确的类型。 我不知道确切的算法,但您可以将其视为 FastAPI 将尝试以未知顺序使用这些模型,并且 FastAPI 将选择第一个通过验证的模型作为此参数的类型。
要解决这个问题,您可以使用受歧视的工会。这样您就可以向 FastAPI 提供选择正确模型的标准。
在某些情况下,您可以通过向所有模型添加
model_config = ConfigDict(extra="forbid")
来解决此问题。如果存在未知字段,这将迫使模型验证失败。因此,当输入 JSON 中有字段 SheetConfigCreate
时,config
将不会通过验证。
以下方法也有帮助。 定义新类型:
KnowledgeConfig: TypeAlias = Annotated[Union[DocumentConfigCreate, SheetConfigCreate, ImageConfigCreate], Field(union_mode='left_to_right')]
并使用它代替Union[DocumentConfigCreate, ...]