You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI返回嵌套对象时丢失字段问题排查求助

FastAPI接口IngredientBody字段缺失问题排查与解决

FastAPI GET接口返回包含IngredientBody列表的ComponentBody时,ingredientMeasurement和ingredientUnit字段未返回,但调试确认数据库已获取到对应数据,单独返回IngredientBody列表时所有字段正常,DirectionBody无此异常。

问题根源

代码中存在字段映射不匹配的问题:

  • 数据库模型IngredientModel的字段为measurement和unit
  • Pydantic模型IngredientBody对应的字段为ingredientMeasurement和ingredientUnit
  • Service层直接将数据库查询得到的IngredientModel列表赋值给componentBody.componentIngredients,Pydantic自动序列化时无法识别字段映射关系,导致这两个字段未被正确转换。
  • 而DirectionBody的字段名与DirectionModel完全对应(如directionText),因此序列化正常。

解决方案

方案1:手动转换模型对象

在Service层将IngredientModel逐个转换为IngredientBody对象,明确字段映射关系:

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

    component = componentDataProvider.findComponentById(componentId)

    # 手动转换IngredientModel到IngredientBody
    ingredient_bodies = [
        IngredientBody(
            ingredientId=ing.ingredientId,
            ingredientName=ing.ingredientName,
            ingredientMeasurement=ing.measurement,
            ingredientUnit=ing.unit
        ) for ing in ingredients
    ]

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

    return componentBody

方案2:使用Pydantic字段别名

在IngredientBody中为字段添加别名,匹配数据库模型的字段名,让Pydantic自动识别映射:

from pydantic import Field

class IngredientBody(BaseModel):
    ingredientId: int | None = None
    ingredientName: str
    ingredientMeasurement: float = Field(alias="measurement")
    ingredientUnit: str = Field(alias="unit")

    def toModel(self):
        model = IngredientModel()
        model.ingredientId = self.ingredientId
        model.ingredientName = self.ingredientName
        model.measurement = self.ingredientMeasurement
        model.unit = self.ingredientUnit
        return model

方案3:统一字段名(可选)

若项目允许,将IngredientBody的字段名修改为与IngredientModel一致,无需额外转换即可直接赋值:

class IngredientBody(BaseModel):
    ingredientId: int | None = None
    ingredientName: str
    measurement: float
    unit: str

    def toModel(self):
        model = IngredientModel()
        model.ingredientId = self.ingredientId
        model.ingredientName = self.ingredientName
        model.measurement = self.measurement
        model.unit = self.unit
        return model

此方案需同步修改所有使用IngredientBody的代码,适合字段名未广泛使用的场景。

验证

修改后重新运行接口,componentIngredients列表中的每个对象应包含目标字段,且值与数据库数据一致。

内容的提问来源于stack exchange,提问作者murrag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 00:07:26