当数据存在时,FastAPI的响应会省略嵌套对象中的字段

编程语言 2026-07-09

我有一个FastAPI的 GET端点,简而言之,它从数据库获取信息,将其整理成一个包含两个字段的对象,这两个字段分别是不同对象的列表,然后返回这个父对象。大多数情况下它运作良好,数据可以找到并几乎按预期返回。然而其中一个对象列表只返回这四个字段中的其中两个,我不确定为什么。稍后我会把相关代码放在最后。

我已经尝试对所有内容使用标准的Pydantic模型,但仍然遇到这个问题,于是我做了一些“调试”,在返回之前把值打印到控制台,所有字段都显示有值,因此我知道字段确实存在且已正确从数据库取回。此外,我还尝试按照这些问题中的建议答案加入 Deeply nested json objects with fastapi and pydanticGetting nested responses from self related model 的做法,但没有看到任何差异。为测试起见,我还把返回改成只返回父对象中的其中一个列表,而不是整个父对象;这样做时数据全部按预期返回,这进一步证明数据确实存在且被检索。我最后尝试的是手动进行JSON编码并按照文档中的方法返回一个JSON响应,但也仍然没有成功。

Router endpoint

def getComponentDetail(componentId: int):
    data = componentService.getComponentDetail(componentId)

    return data

Service Method

def getComponentDetail(componentId):
    ingredients = componentDataProvider.findIngredientsByComponentId(componentId)
    directions = componentDataProvider.findDirectionsByComponentId(componentId)

    component = componentDataProvider.findComponentById(componentId)

    componentBody = ComponentBody()
    componentBody.componentName = component.componentName
    componentBody.componentId = component.componentId
    componentBody.componentLink = component.originalLink
    componentBody.componentNotes = component.componentNotes
    componentBody.componentIngredients = ingredients
    componentBody.componentDirections = directions

    return componentBody

Find component method

def findIngredientsByComponentId(componentId):
    with Session(engine) as session:
        statement = select(IngredientModel).where(IngredientModel.componentId == componentId)
        result = session.exec(statement)

        return result.all()

Find ingredients method

def findIngredientsByComponentId(componentId):
    with Session(engine) as session:
        statement = select(IngredientModel).where(IngredientModel.componentId == componentId)
        result = session.exec(statement)

        return result.all()

Find directions method

def findDirectionsByComponentId(componentId):
    with Session(engine) as session:
        statement = select(DirectionModel).where(DirectionModel.componentId == componentId)
        result = session.exec(statement)

        return result.all()

Component Body Class

class ComponentBody(BaseModel):
    componentId: int | None = None
    componentName: str | None = None
    componentLink: str | None = None
    componentNotes: str | None = None
    componentIngredients: list[IngredientBody] | None = []
    componentDirections: list[DirectionBody] | None = []


    def toModel(self):
        model = ComponentModel()

        model.componentId = self.componentId
        model.componentName = self.componentName
        model.originalLink = self.componentLink
        model.componentNotes = self.componentNotes

        return model

Ingredient Body class

class IngredientBody(BaseModel):
    ingredientId: int | None = None
    ingredientName: str
    ingredientMeasurement: float
    ingredientUnit: str

    def toModel(self):
        model = IngredientModel()

        model.ingredientId = self.ingredientId
        model.ingredientName = self.ingredientName
        model.measurement = self.ingredientMeasurement
        model.unit = self.ingredientUnit

        return model

Direction Body class

class DirectionBody(BaseModel):
    directionId: int | None = None
    directionOrder: int | None = None
    directionText: str | None = None

    def toModel(self):
        model = DirectionModel()

        model.directionId = self.directionId
        model.directionText = self.directionText
        model.directionOrder = self.directionOrder

        return model

我省略了所有导入以便简洁,ingredientModel就是有问题的那个对象,奇怪的是directionBody即使没有添加我试过的那些额外测试也能返回全部三个字段。需要说明的是,ingredientMeasurement和 ingredientUnit是没有返回的两个字段,控制台也没有显示任何错误。

解决方案

我最终搞清楚了。我直接从数据库取出一个模型后就返回了一个响应体,没有进行正确的转换。对另外一个对象之所以能工作,凭我最大的猜测,可能是因为它的响应体与模型之间的属性名完全相同。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章