从 sqlmodel 获取连接表作为 fastapi 中的嵌套响应模型

2024-04-09

我无法弄清楚如何使用 fastapi 和 sqlmodel 显示一对多关系。我读过这篇文章question https://stackoverflow.com/questions/72870598/getting-nested-joined-tables-to-display-in-the-openapi-interface-provided-by-f/73372947?noredirect=1#comment131875135_73372947但我的情况似乎略有不同。特别是在函数调用中。

这是我的schemas.py:

from typing import Optional
from sqlmodel import Field, Relationship, SQLModel

class BinaryBase(SQLModel):
    product_id: int
    software_install_path: Optional[str] = None
    host_id: int = Field(foreign_key="host.id", nullable=False)


class Binary(BinaryBase, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    host_id: int = Field(foreign_key="host.id", nullable=False)
    host: "Host" = Relationship(back_populates="binaries")


class HostBase(SQLModel):
    name: str
    region: Optional[str] = None
    os_version: Optional[str] = None
    network: Optional[int] = None


class Host(HostBase, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    binaries: list[Binary] = Relationship(back_populates='host')


class HostReadWithBinary(HostBase):
    bins: list[HostBase] = []


class BinaryReadWithHost(BinaryBase):
    host: BinaryBase

这是我的main.py:

from fastapi import Depends, FastAPI
from sqlmodel import Session, col, select

...

@app.get(
    "/binaries/",
    response_model=list[HostReadWithBinary]
)
def get_binary(name: Optional[str] = None, session: Session = Depends(get_session)) -> list[HostReadWithBinary]:
    query = select(Host).limit(100)
    if name:
        query = query.where(col(Host.name).contains(name.lower()))

    return session.exec(query).all()

The Host表代表1部分和Binary表代表many部分。我想得到所有的回应BinaryBase热切地为所有主机提供属性。但我得到的是这样的:

[
  {
    "name": "hkl20014889",
    "region": "HK",
    "os_version": "Red Hat 6.10",
    "network": 3,
    "bins": []
  },
  {
    "name": "hkl20016283",
    "region": "HK",
    "os_version": "Red Hat 6.10",
    "network": 3,
    "bins": []
  },
.... 

理论上bins应该持有的属性Host表当id in Host joins host_id在二进制中。


你需要意识到,当你定义一个response_model对于路线,它总是尝试解析来自路线处理函数的任何数据(get_binary在本例中)通过该模型。这基本上是通过调用来完成的.from_orm https://docs.pydantic.dev/usage/models/#orm-mode-aka-arbitrary-class-instances响应模型上的方法,它遍历其上定义的所有字段并尝试查找相应的您传递给它的对象的属性(即具有相同的名称)。

您指定的模型(在列表中,但参数成立)是HostReadWithBinary。除了在其父模型上定义的字段之外HostBase它只有字段bins,这应该是一个列表HostBase.

首先我觉得你meant声明bins字段的类型为list[BinaryBase], not list[HostBase]。如果您正确命名了该字段,这会导致错误,但这就是您的第二个错误出现的地方。

您还在响应模型中命名了该字段bins,但是您的处理程序函数执行一个返回列表的查询Host模型实例。那个型号不具有 a bins场地。它有一个名为binaries。这意味着当from_orm方法到达HostReadWithBinary.bins字段,它检查是否对应Host实例有一个名为bins。它没有找到,但没问题,因为你设置了默认值HostReadWithBinary.bins,即空列表[],这就是每个生成的响应模型实例上设置的内容。

因此,您应该能够通过更改响应模型定义来修复错误,如下所示:

class HostReadWithBinary(HostBase):
    binaries: list[BinaryBase] = []

或者,您可以更改您的关系字段的名称Host model:

class Host(HostBase, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    bins: list[Binary] = Relationship(back_populates='host')


class HostReadWithBinary(HostBase):
    bins: list[BinaryBase] = []

它们必须相同,否则将一种模型的对象解析为另一种模型将无法(正确)工作。


旁注:您还错误地注释了host场上BinaryReadWithHost with BinaryBase代替HostBase.

PS:我还刚刚注意到一个与类型注释相关的小错误。您将路由处理函数的返回类型声明为list[HostReadWithBinary],但这不是它返回的内容。它返回list[Host]。这是对响应模型的误解的一部分。这装饰的返回的是您的路线版本list[HostReadWithBinary]。您的路线处理程序get_binary本身(即装饰之前)返回list[Host],即then传递给它周围的包装器,该包装器将其解析为list[HostReadWithBinary]并按其方式发送该数据(最终发送给客户端)。这个包装器操作显然发生在幕后,并且是 FastAPI 装饰器魔法的一部分。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 sqlmodel 获取连接表作为 fastapi 中的嵌套响应模型 的相关文章

  • 无法在我的 Django 项目中使用 Sphinx 生成自动文档

    我正在向我的 Django 项目添加文档 github链接 https github com augustakingfoundation queryjane app 该项目是开源的 使用sphinx 但是当尝试生成python文件的auto
  • AttributeError:'function'对象在pandas中没有属性'bar'

    我有一个 pandas 数据框 它是 pandas 数据框类型 如下所示 type df Out 176 pandas core frame DataFrame 但是 当我尝试在此数据框上使用任何绘图函数 如条形图 时 会出现如下错误 df
  • 使用单个文件的 Python 日志记录(函数名、文件名、行号)

    我正在尝试了解应用程序的工作原理 为此 我将调试命令插入作为每个函数主体的第一行 目的是记录函数的名称以及向日志输出发送消息的行号 代码内 最后 由于这个应用程序由许多文件组成 我想创建一个日志文件 以便我可以更好地理解应用程序的控制流 这
  • 区分大小写的实体识别

    我的关键字全部以小写形式存储 例如 折扣耐克鞋 我正在尝试对其执行实体提取 我遇到的问题是 spaCy 在 NER 方面似乎区分大小写 请注意 我不认为这是 spaCy 特有的 当我跑步时 doc nlp u i love nike sho
  • 如何检索分配给 Django 中的组的所有权限

    我正在执行一项任务来检索分配给 Django 中的组的一组权限 我可以使用以下代码获取创建的组 但无法使用它来获取分配给它们的权限 from django contrib auth models import Group Permissio
  • 检查子字符串是否在字符串列表中?

    我之前已经找到了这个问题的一些答案 但它们对于当前的Python版本来说似乎已经过时了 或者至少它们对我不起作用 我想检查字符串列表中是否包含子字符串 我只需要布尔结果 我找到了这个解决方案 word to check or wordlis
  • Python 中 time.sleep 和多线程的问题

    我对 python 中的 time sleep 函数有疑问 我正在运行一个脚本 需要等待另一个程序生成 txt 文件 虽然 这是一台非常旧的机器 所以当我休眠 python 脚本时 我遇到了其他程序不生成文件的问题 除了使用 time sl
  • 如何在动态执行的代码字符串中使用inspect.getsource?

    如果我在文件中有这段代码 import inspect def sample p1 print p1 return 1 print inspect getsource sample 当我运行脚本时 它按预期工作 在最后一行 源代码sampl
  • 如果另一列中的值为空,则删除重复项 - Pandas

    我拥有的 df Name Vehicle Dave Car Mark Bike Steve Car Dave Steve 我想从 名称 列中删除重复项 但前提是 车辆 列中的相应值为空 我知道我可以使用 df dropduplicates
  • Django Web 应用程序中的 SMTP 问题

    我被要求向使用 Django Python 框架实现的现有程序添加一个功能 此功能将允许用户单击一个按钮 该按钮将显示一个小对话框 表单以输入值 我确实编写了一些代码 显示电子邮件已发送的消息 但实际上 它没有发送 My code from
  • 一个类似 dict 的 Python 类

    我想编写一个自定义类 其行为类似于dict 所以 我继承自dict 不过 我的问题是 我是否需要创建一个私有的dict我的成员 init 方法 我不明白这个有什么意义 因为我已经有了dict如果我只是继承自的行为dict 谁能指出为什么大多
  • 错误:尝试使用 scrappy 登录时出现 raise ValueError("No element found in %s" % response)

    问题描述 我想从我大学的bbs上抓取一些信息 这是地址 http bbs byr cn http bbs byr cn下面是我的蜘蛛的代码 from lxml import etree import scrapy try from scra
  • Python 或 C 语言中的 Matlab / Octave bwdist()

    有谁知道 Matlab Octave bwdist 函数的 Python 替代品 此函数返回给定矩阵的每个单元格到最近的非零单元格的欧几里得距离 我看到了一个 Octave C 实现 一个纯 Matlab 实现 我想知道是否有人必须用 AN
  • 使用 FastAPI 传输 LangChain OpenAI 响应 [重复]

    这个问题在这里已经有答案了 我想将 OpenAI 的响应直接传输到 FastAPI 的端点 Code 在我的threads handler py 位于单独的文件夹中 中 我有以下函数askQuestion def askQuestion s
  • 有没有办法拉伸整个显示图像以适应给定的分辨率?

    我最近一直在使用pygame制作游戏 遇到了一个小问题 基本上 我希望能够将屏幕上的整个图像 我已经传输到它的所有内容 拉伸到用户将窗口大小调整到的分辨率 我在 pygame 和堆栈溢出的文档中搜索了很多 但我似乎找不到答案 这可能吗 我的
  • 在 anaconda 环境下运行 qsub

    我有一个程序 通常在 Linux 的 conda 环境中运行 因为我用它来管理我的库 指令如下 source activate my environment python hello world py 我怎样才能跑你好世界 py在与 PBS
  • 为什么我的 PyGame 应用程序根本不运行?

    我有一个简单的 Pygame 程序 usr bin env python import pygame from pygame locals import pygame init win pygame display set mode 400
  • 在 python 中使用高精度时间戳

    嘿 我正在使用 python 处理日期时间 我想知道解析这个时间戳的最佳方法是什么 时间戳是ISO标准 这里是一个例子 2010 06 19T08 17 14 078685237Z 现在到目前为止我已经使用过 time datetime d
  • 如何在 Qt 中以编程方式制作一条水平线

    我想弄清楚如何在 Qt 中制作一条水平线 这很容易在设计器中创建 但我想以编程方式创建一个 我已经做了一些谷歌搜索并查看了 ui 文件中的 xml 但无法弄清楚任何内容 ui 文件中的 xml 如下所示
  • 防止 Ada DLL 中的名称损坏

    有没有一种简单的方法可以防止在创建 Ada DLL 时 Ada 名称被破坏 这是我的 adb 代码 with Ada Text IO package body testDLL is procedure Print Call is begin

随机推荐