python / pydantic / fastapi-将此数据结构描述为模型模型?

发布于 2025-02-09 08:17:32 字数 3201 浏览 1 评论 0原文

问题

我有一个数据结构的嵌套列表的数据结构,我试图使用Pydantic模型在Fastapi中构建一个response_model,但事实证明这是不可能的。一旦我应用response_model =指示数据从API返回。如果我删除response_model =指令对API的相同查询会导致数据返回正常并且具有内容。

数据看起来如下:

[
    {
        'code': 'trabant',
        'description': 'East German Trabant',
        'listings': [
            {
                 id: 1000,
                 cat_no: "Trabi1",
                 descript: "Trabant Interior Mirror"
                 price: Decimal(16.95),
                 veh: 'trabant',
                 sec: 'interior'
             },
             {
                 id: 1001
                 cat_no: "Trabi2",
                 descript: "Trabant Interior Clock"
                 price: Decimal(56.95),
                 veh: 'trabant',
                 sec: 'interior'
             }
         ]
    },
    {
        'code': 'skoda',
        'description': 'Czech Skoda',
        'listings': [
            {
                  id: 2001,
                  cat_no: "Skoda5",
                  descript: "Front Grille",
                  price: Decimal(36.95),
                  veh: 'skoda',
                  sec: 'bodywork'
             },
             {
                  id: 2002
                  cat_no: "Skoda6",
                  descript: "Skoda Grille Badge - Front"
                  price: Decimal(16.95),
                  veh: 'skoda',
                  sec: 'bodywork'
             }
        ]
    }
]

归结为其结构时的看起来像:

] # root list
    { #can be any vehicle in a list of 40+
        'code': #vehicle's db code
        'description': #vehicle's textual name>,
        'listings': [ #list of catalogue items for this vehicle
            {
                id: #db id,
                cat_no: #Customer SKU,
                descript: #Description of a part,
                price: #Decimal value for price, no evil floats here!,
                veh: #db code for vehicle,
                sec: #db code for section
            }
        ]
    }
]

我尝试使用以下pydantic模型来描述它:

class ORMBaseModel(BaseModel):
    class Config:
        orm_mode = True

class CatListing(ORMBaseModel):
    id: int
    cat_no: str
    descript: str
    sec: str
    veh: str
    price: Decimal

class VehicleCatListings(ORMBaseModel):
    code: str
    description: str
    listings: List[ CatListing ]

class ListOfCatListings(ORMBaseModel):
    List[ VehicleCatListings ]

但是,当我使用以下途径时:我在in in then oter ote ote ofer:

@app.get("/api/cat_no/{ff_no}/listings", response_model=schema.ListOfCatListings)
def getListings(ff_no: str, db: Session = Depends(databases.getDb)):
    listings = crud.catalogue.getListings(db, ff_no) #db request that returns data output as shown above

    if listings is None:
        raise HTTPException(status_code=404, detail="FF No catalogue listings not found")
    
    return listings

我得到一个空白对象{} in返回,好像Pydantic模型以某种方式忽略了数据。但是,我发现很难调试。

NB:我不在一个出售稀有东欧汽车零件的地方工作,我只是以这些为例;)

Problem

I have a data structure of nested lists of Dicts that I am trying to build a response_model for in FastAPI using Pydantic models but it's proving so far impossible. As soon as I apply the response_model= directive the data returns empty from the API. If I remove the response_model= directive the same query to the API results in data returning just fine and has content.

The Data looks like the following:

[
    {
        'code': 'trabant',
        'description': 'East German Trabant',
        'listings': [
            {
                 id: 1000,
                 cat_no: "Trabi1",
                 descript: "Trabant Interior Mirror"
                 price: Decimal(16.95),
                 veh: 'trabant',
                 sec: 'interior'
             },
             {
                 id: 1001
                 cat_no: "Trabi2",
                 descript: "Trabant Interior Clock"
                 price: Decimal(56.95),
                 veh: 'trabant',
                 sec: 'interior'
             }
         ]
    },
    {
        'code': 'skoda',
        'description': 'Czech Skoda',
        'listings': [
            {
                  id: 2001,
                  cat_no: "Skoda5",
                  descript: "Front Grille",
                  price: Decimal(36.95),
                  veh: 'skoda',
                  sec: 'bodywork'
             },
             {
                  id: 2002
                  cat_no: "Skoda6",
                  descript: "Skoda Grille Badge - Front"
                  price: Decimal(16.95),
                  veh: 'skoda',
                  sec: 'bodywork'
             }
        ]
    }
]

Which when boiled down to it's structure looks like:

] # root list
    { #can be any vehicle in a list of 40+
        'code': #vehicle's db code
        'description': #vehicle's textual name>,
        'listings': [ #list of catalogue items for this vehicle
            {
                id: #db id,
                cat_no: #Customer SKU,
                descript: #Description of a part,
                price: #Decimal value for price, no evil floats here!,
                veh: #db code for vehicle,
                sec: #db code for section
            }
        ]
    }
]

I tried to describe it using these Pydantic models:

class ORMBaseModel(BaseModel):
    class Config:
        orm_mode = True

class CatListing(ORMBaseModel):
    id: int
    cat_no: str
    descript: str
    sec: str
    veh: str
    price: Decimal

class VehicleCatListings(ORMBaseModel):
    code: str
    description: str
    listings: List[ CatListing ]

class ListOfCatListings(ORMBaseModel):
    List[ VehicleCatListings ]

But when I use the following route:

@app.get("/api/cat_no/{ff_no}/listings", response_model=schema.ListOfCatListings)
def getListings(ff_no: str, db: Session = Depends(databases.getDb)):
    listings = crud.catalogue.getListings(db, ff_no) #db request that returns data output as shown above

    if listings is None:
        raise HTTPException(status_code=404, detail="FF No catalogue listings not found")
    
    return listings

I get a blank object {} in return as if the pydantic model is ignoring the data somehow. I am however finding it hard to debug.

NB: I don't work for a place that sells rare Eastern European Car parts, I just used these as an example ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兲鉂ぱ嘚淚 2025-02-16 08:17:32

好的,所以在砖墙上大量敲打我的头后,事实证明这是一个非常普遍的问题,并且已经在Stackoverflow上提到了几次。这里的错是:

class ListOfCatListings(ORMBaseModel):
    List[ VehicleCatListings ]

应该是:

class ListOfCatListings(ORMBaseModel):
    __root__: List[ VehicleCatListings ]

这实现了我需要的。

我希望这对别人有帮助。

Okay so after a lot of banging my head on a brick wall it turns out this is a very common problem and it's mentioned a few times on Stackoverflow already. The fault here is that:

class ListOfCatListings(ORMBaseModel):
    List[ VehicleCatListings ]

Should be:

class ListOfCatListings(ORMBaseModel):
    __root__: List[ VehicleCatListings ]

This achieves what I needed.

I hope this helps someone else out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文