【问题标题】:How to translate SQLAlchemy result rows into nested dicts如何将 SQLAlchemy 结果行转换为嵌套字典
【发布时间】:2019-12-05 07:41:05
【问题描述】:

我正在评估在 async/await FastAPI 应用程序中使用 SQLAlchemy 的潜在设置。我目前正在使用declarative_base 类组合模型和查询,然后使用Databases 执行查询(对于模型类,语法更具可读性和易于编写;直接使用 SQLAlchemy 核心表不是我最喜欢的活动)。这一切都很好。

此时,我有 SQLAlchemy 结果行,但我需要将它们转换为通用 dicts,由于急切加载的关系可能会嵌套(在此环境中只有我将支持的类型)。我不能使用 SQLAlchemy 的 ORM,因为 1)我没有 enginesession; 2) ORM 假设它可以在需要加载对象时访问数据库,这在 async/await FastAPI 应用程序中并非如此。

有没有人对如何实现这一点有想法或指示?我正在努力弄清楚如何将结果行与特定的关系键相关联,特别是。我一直在 SQLAlchemy 内部寻找想法,但它非常不透明,因为其中很多假设我的设置中不存在整个对象缓存和会话/引擎管理层。

我可以使用的两件事:

  1. 如何将 table_1_column_name 等列名称映射到特定模型及其属性
  2. 如何检测和映射关系(可能不止一层)

感谢您提供的任何帮助!

更新:您可以在此处找到一个可运行的示例:https://gist.github.com/onecrayon/dd4803a5099061fa48d52f2d4bc2396b(有关我需要弄清楚如何通过映射将 RowProxy 转换为嵌套字典的相关位置,请参见第 92-109 行查询列名到 SQLAlchemy 模型上的名称)。

【问题讨论】:

    标签: python sqlalchemy async-await fastapi


    【解决方案1】:

    如果你是db first,sqlalchemy的execute方法通常会返回一个Result Proxy对象,你可以通过fetchone、first、fetchall等方法获取它的结果,然后将其强制转换为list或字典。 你也可以看看this dock

    【讨论】:

    • 我没有使用 SQLAlchemy 执行方法(这需要引擎/会话,并且我正在通过数据库执行具有异步/等待的数据库查询,如我的帖子中所述)。我确实有可以通过键访问的行,但它是生成的 SQLAlchemy 查询中的键,我需要帮助确定从该键映射到模型对象键的策略。
    • 查看这个要点以获得可运行的示例;适用于这个问题的代码是第 92-109 行:gist.github.com/onecrayon/dd4803a5099061fa48d52f2d4bc2396b
    【解决方案2】:

    如果结果是原始 SQLAlchemy 行而不是 ORM 映射实例,Casting the object into a dict 应该可以工作。

    从您对另一个答案的评论来看,您似乎需要将结果映射回 ORM 实例。你可以定义declarative mappings,这样你的结果就会被翻译回一个python实例。

    【讨论】:

    • 我实际上是在将结果映射到字典中,但诀窍是如果它们作为查询的一部分加载,我想包含关系。因此,对于每个父项,我可能有多个重复行,每行代表一个子项。然后,我想生成一个包含单个父项的列表,其中包含一个child 属性,该属性是结果集中每个相关child 项的列表。有关示例,请参阅原始问题中链接的要点。
    【解决方案3】:

    SQLALchemy 对象可以选择以 dict 形式返回 - 这是帮助您的 SQLALchemy 源文档。 https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.util.KeyedTuple._asdict

    或者您可以使用https://pythonhosted.org/dictalchemy,它作为 SQLALchemy 之上的包装器。

    希望对您有所帮助。

    【讨论】:

    • DictAlchemy 并不是我所需要的,因为它将 ORM 结果映射到字典,我特别需要将 RowProxy 结果包装到字典(包括关系,如果它们作为查询的一部分加载) .不过,我会尝试asdict()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2020-09-03
    • 2013-12-07
    • 2019-12-09
    相关资源
    最近更新 更多