通过递归 CTE 使用 SQLAlchemy 获取层次结构的顶级父 ID

2023-12-10

我有这样一个案例:

|               Note table               |
|---------------------|------------------|
|          id         |     parent_id    |
|---------------------|------------------|
|          1          |     Null         |
|---------------------|------------------|
|          2          |      1
|---------------------|------------------|
|          3          |      2
|---------------------|------------------|
|          4          |      3
|---------------------|------------------|

我想要实现的是获取顶级父 ID。 在这种情况下,如果我传递 ID 号 4,我将得到 Id 1,因为 Id 1 是顶级父级。 当parent_id 达到null 时,意味着该id 是顶级父级。

我已经尝试过了,但返回的是我传递给函数的 Id。

  def get_top_level_Note(self, id: int):


        hierarchy = self.db.session.query(Note).filter(Note.id == id).cte(name="hierarchy", recursive=True)

        parent = aliased(hierarchy, name="p")
        children = aliased(Note, name="c")

        hierarchy = hierarchy.union_all(self.db.session.query(children).filter(children.parent_id == parent.c.id))

        result = self.db.session.query(Note).select_entity_from(hierarchy).all()

使用名为“note”的现有表

id          parent_id
----------- -----------
11          NULL
22          11
33          22
44          33
55          NULL
66          55

PostgreSQL 中的一些混乱表明

WITH RECURSIVE parent (i, id, parent_id)
AS (
    SELECT 0, id, parent_id FROM note WHERE id=44
UNION ALL
    SELECT i + 1, n.id, n.parent_id 
    FROM note n INNER JOIN parent p ON p.parent_id = n.id 
    WHERE p.parent_id IS NOT NULL
)
SELECT * FROM parent ORDER BY i;

returned

i           id          parent_id
----------- ----------- -----------
0           44          33
1           33          22
2           22          11
3           11          NULL

因此我们可以通过将最后一行更改为来获得顶级父级

WITH RECURSIVE parent (i, id, parent_id)
AS (
    SELECT 0, id, parent_id FROM note WHERE id=44
UNION ALL
    SELECT i + 1, n.id, n.parent_id 
    FROM note n INNER JOIN parent p ON p.parent_id = n.id 
    WHERE p.parent_id IS NOT NULL
)
SELECT id FROM parent ORDER BY i DESC LIMIT 1 ;

返回

id
-----------
11

因此,要将其转换为 SQLAlchemy (1.4):

from sqlalchemy import (
    create_engine,
    Column,
    Integer,
    select,
    literal_column,
)
from sqlalchemy.orm import declarative_base

connection_uri = "postgresql://scott:[email protected]/test"
engine = create_engine(connection_uri, echo=False)

Base = declarative_base()


class Note(Base):
    __tablename__ = "note"
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer)


def get_top_level_note_id(start_id):
    note_tbl = Note.__table__
    parent_cte = (
        select(
            literal_column("0").label("i"), note_tbl.c.id, note_tbl.c.parent_id
        )
        .where(note_tbl.c.id == start_id)
        .cte(name="parent_cte", recursive=True)
    )
    parent_cte_alias = parent_cte.alias("parent_cte_alias")
    note_tbl_alias = note_tbl.alias()
    parent_cte = parent_cte.union_all(
        select(
            literal_column("parent_cte_alias.i + 1"),
            note_tbl_alias.c.id,
            note_tbl_alias.c.parent_id,
        )
        .where(note_tbl_alias.c.id == parent_cte_alias.c.parent_id)
        .where(parent_cte_alias.c.parent_id.is_not(None))
    )
    stmt = select(parent_cte.c.id).order_by(parent_cte.c.i.desc()).limit(1)
    with engine.begin() as conn:
        result = conn.execute(stmt).scalar()
    return result


if __name__ == "__main__":
    test_id = 44
    print(
        f"top level id for note {test_id} is {get_top_level_note_id(test_id)}"
    )
    # top level id for note 44 is 11

    test_id = 66
    print(
        f"top level id for note {test_id} is {get_top_level_note_id(test_id)}"
    )
    # top level id for note 66 is 55
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过递归 CTE 使用 SQLAlchemy 获取层次结构的顶级父 ID 的相关文章

  • celery任务eta已关闭,使用rabbitmq

    我使用教程中的默认设置和在 ubuntu 上运行的rabbitmq 使 Celery 任务正常进行 当我毫不延迟地安排任务时 一切都很好 但是当我给他们一个预计时间时 他们会被安排在未来 就好像我的时钟在某个地方关闭了一样 下面是一些请求任
  • 在 SQLAlchemy 中,过滤器是在连接之前还是之后应用?

    使用 SQLAlchemy 我执行如下查询 import models as m import sqlalchemy as sa s session maker q s query m ShareCount m Article join m
  • 创建 xyz 海拔数据的曲面图

    我正在尝试用 python 创建一座山的表面图 其中我有一些 xyz 数据 最终结果应该类似于that https i stack imgur com rKQV0 png 该文件的格式如下 616000 0 90500 0 3096 712
  • 删除 tkinter 文本默认绑定

    我正在制作一个简单的 tkinter 文本编辑器 但我想要所有默认绑定文本小部件如果可能的话删除 例如当我按Ctrl i它默认插入一个制表符 我制作了一个事件绑定来打印文本框中有多少行 我将事件绑定设置为Ctrl i以及 当我运行它时 它会
  • pandas 数据框的最大大小

    我正在尝试使用读取一个有点大的数据集pandas read csv or read stata功能 但我不断遇到Memory Errors 数据帧的最大大小是多少 我的理解是 只要数据适合内存 数据帧就应该没问题 这对我来说不应该是问题 还
  • lmfit模型拟合然后预测

    我正在领养lmfit进行曲线拟合并使用拟合模型进行预测 然而下面的代码并没有达到我想要的效果 能否请你帮忙 谢谢 import numpy as np from lmfit import Model def linearModel x a0
  • matplotlib:渲染到缓冲区/访问像素数据

    我想使用 matplotlib 生成的图作为 OpenGL 中的纹理 到目前为止 我遇到的 matplotlib 的 OpenGL 后端要么不成熟 要么已经停止使用 所以我想避免使用它们 我当前的方法是将图形保存到临时 png 文件中 并从
  • 右键单击 QPushButton 上的 contextMenu

    对于我的应用程序 我在 Qt Designer 中创建了一个 GUI 并将其转换为 python 2 6 代码 关于一些QPushButton 与设计器创建 我想添加右键单击上下文菜单 菜单选项取决于应用程序状态 如何实现这样的上下文菜单
  • 提高光线追踪命中功能的性能

    我有一个简单的 python 光线追踪器 渲染 200x200 的图像需要 4 分钟 这对于我的口味来说绝对是太多了 我想改善这种情况 几点 我为每个像素发射多条光线 以提供抗锯齿功能 每个像素总共发射 16 条光线 200x200x16
  • 类变量:“类列表”与“类布尔值”[重复]

    这个问题在这里已经有答案了 我不明白以下示例的区别 一次类的实例可以更改另一个实例的类变量 而另一次则不能 示例1 class MyClass object mylist def add self self mylist append 1
  • Django 1.7:如何使用 html/css 文件作为模板发送电子邮件

    从 Django 1 7 开始 可以send email 使用新参数 html message 不幸的是 没有关于如何使用它的全面指南 新手友好 或者至少我找不到它 我需要使发送的电子邮件变得漂亮 因此 我试图弄清楚如何将我的消息包含到 h
  • Python GTK3 Treeview 向上或向下移动选择

    如何在树视图中向上或向下移动所选内容 我的想法是 我可以使用向上和向下按钮将选择向上移动一行或向下移动一行 我的 Treeview 使用 ListStore 不确定这是否重要 首先 我将使用我熟悉的 C 代码 如果您在将其翻译为 Pytho
  • 在Python中随机交错2个数组

    假设我有两个数组 a 1 2 3 4 b 5 6 7 8 9 我想将这两个数组交错为变量 c 注意 a 和 b 不一定具有相同的长度 但我不希望它们以确定性的方式交错 简而言之 仅仅压缩这两个数组是不够的 我不想要 c 1 5 2 6 3
  • 如何在类型提示中定义元组或列表的大小

    有没有办法在参数的类型提示中定义元组或列表的大小 目前我正在使用这样的东西 from typing import List Optional Tuple def function name self list1 List Class1 if
  • 关闭正在运行代码的 IPython Notebook

    怎么运行的 我在 IPython Notebook 中运行了一些代码 一些迭代工作 我不小心关闭了正在运行的笔记本的浏览器 但回到 IPython 仪表板 我发现这个特定的笔记本尚未关闭 所以如果我再次打开笔记本 我会在它正在执行的代码前面
  • 如何创建简单的梯度下降算法

    我正在研究简单的机器学习算法 从简单的梯度下降开始 但在尝试用 python 实现它时遇到了一些麻烦 这是我试图重现的示例 我获得了有关房屋的数据 居住面积 以英尺为单位 和卧室数量 以及最终的价格 居住面积 英尺2 2104 卧室 3 价
  • 在自定义 keras 层的调用函数中传递附加参数

    我创建了一个自定义 keras 层 目的是在推理过程中手动更改前一层的激活 以下是基本层 它只是将激活值乘以一个数字 import numpy as np from keras import backend as K from keras
  • 如何仅读取 CSV 文件每行的第一列 [重复]

    这个问题在这里已经有答案了 如何在Python中读取CSV文件每行的第一列 我的数据是这样的 1 abc 2 bcd 3 cde 我只需要循环第一列的值 另外 当我在 calc 中打开 csv 文件时 每行中的数据都在同一个单元格中 这正常
  • 将二进制数转换为包含每个二进制数的数组

    我试图将二进制值转换为每个 1 0 的列表 但我得到默认的二进制值而不是列表 我有一个字符串 我将每个字符转换为二进制 它给了我一个列表 其中每个字符都有一个字符串 现在我试图将每个字符串拆分为值为 0 1 的整数 但我什么也得不到 if
  • 美丽的汤刮 - 登录凭据不起作用

    尝试使用登录凭据抓取页面 payload email gmail com password urls login url https www spotrac com signin url https www spotrac com nba

随机推荐

  • Python Matplotlib 滑块已绘制但不移动或更新

    我正在尝试绘制一个散点图 其中一个点根据滑块调整的参数移动 我需要参数是坐标列表中的位置 我拥有它 因此可以绘制散点图 并且我可以通过更改位置来手动移动点 但是当我尝试实现滑块时 它会显示 但无法更新绘图 任何帮助都会很棒 到目前为止我所拥
  • Catia VBA 到 .CATScript(针对“集合”类型)

    在我的 VBA 代码中 我使用以下内容 Dim docsToSave As Scripting Dictionary Set docsToSave New Scripting Dictionary Dim toRemove As Colle
  • Matlab 上 Z 归一化 (z-score) 函数的反函数

    在Matlab R2014a中我有信心使用z分数 x 功能 function z mu sigma zscore x flag dim if isequal x z return end if nargin lt 2 flag 0 end
  • 在 JPanel 上添加 .GIF 时显示黑色方块

    我的问题是 当将 GIF 添加到 JPanel 时 它会显示 GIF 的黑色方形背景 在JPanel上添加时的结果 当我使用这一行时会发生这种情况 p2 add loadBar where p2 new JPanel 但是 当我在 JFra
  • 在 swift 中使用简单 Ping (iOS)

    我正在尝试使用 Apple 的类 Simple Ping 但我无法使其正常工作 当我运行示例 mac os x 项目时 它正在工作 2015 06 17 00 03 22 569 SimplePing 20386 3133535 ping
  • Angular 5 插入动态输入属性

    我想将动态属性插入到输入 html 标记中 但我不知道该怎么做 我从组件端得到了这段代码 import Component OnInit from angular core Component selector app transclusi
  • Web 套接字在 Firefox 12 中不工作

    Firefox 无法与服务器 ws 192 168 0 155 5555 socket server3 php 建立连接 document ready function if WebSocket in window alert not av
  • 将 jQuery 自动完成与 Flask 结合使用

    这个问题之前已经被问过 我想我已经做了我在那里看到的事情 但我真的不知道我做错了什么 我对 jQuery 了解不多 但我会尽力解释我想要做什么 我想根据数据库中的查询自动完成 所以我的模板中有这样的内容
  • 张量流构建错误

    我在构建 Tensorflow 1 1 0 时遇到此错误 Starting local Bazel server and connecting to it ERROR home bishal cache bazel bazel bishal
  • ASP.NET Core 5 和 6 JWT 身份验证始终抛出 HTTP 401 代码

    我想在 ASP NET Core 中实现基于 JWT 的安全性 目前我想要它做的就是读取按钮中的令牌 Html ActionLink Test Oper Home 授权标头并根据我的标准验证它们 我不知道错过了什么 但它总是返回 HTTP
  • 将 prop 从子级传递给父级 React

    In WeatherForecast组件我需要传递函数的返回值appColor进入财产 那么该财产来自WeatherForecast需要传入className of app成分 新的反应 不确定如何将属性从子级传递到组件 class Wea
  • 在webview中加载本地javascript?

    我正在用我自己的广告快速制作移动浏览器 我想运行脚本 我已经注入了 javascript 本地文件 但它在其他窗口中打开并覆盖 webview 内容 是否可以在 webview 页面中运行 javascript 代码 不在其他窗口中 仅在包
  • 列出 knitr 环境(在 R 块中使用 list2env 时出现 R-markdown 错误)

    编辑 我发现问题源于yaml代码 它来自于应用这个解决方案动态命名文件 我相信它创造了一个家长环境knitr代码 因此list2env造成意想不到的行为 需要明确的是 下面的代码在 R 中完美运行 我在用list2env with envi
  • Camera2 API - Android

    我正在尝试使用android提供的新相机api作为camera2 但 CameraManager manager CameraManager getActivity getSystemService Context CAMERA SERVI
  • 检查 JavaScript 中属性是否存在

    我是 JavaScript 新手 对鸭子类型的概念有点困惑 据我所知 我理解了这个概念 但这在我的想法中导致了一个奇怪的结果 我将用下面的例子来解释 我目前正在使用 jQuery Mobile 开发移动 Web 应用程序 有一次我捕捉到了v
  • 使用 has_one 和 Belongs_to 的嵌套路由和 form_for 以及模型

    如何使用嵌套路由映射 has one 模型 以及如何在 RESTful 数据库之后为 localhost 3000 users 1 profile new html erb 添加 form for 用户拥有一份个人资料 Models cla
  • 使用相同的 php 文件显示表单并接收表单数据

    我有一个生成表单的 php 页面 表单的操作属性是页面本身 用户提交表单后 将加载相同的页面 但这次设置了 POST 变量 因此页面运行另一个脚本来处理来自表单的传入数据 我通过使用条件分叉来做到这一点 if isset POST var
  • 获取断点检索地址簿数据

    我正在检索phoneNumbers我得到一个断点 我花了几个小时试图修复它 但仍然没有成功 void textMessage ABAddressBookRef addressBook ABAddressBookCreate NSMutabl
  • 编译器自动绑定(类型推断)泛型类型

    以下代码在 t3 行有编译错误 public
  • 通过递归 CTE 使用 SQLAlchemy 获取层次结构的顶级父 ID

    我有这样一个案例 Note table id parent id 1 Null 2 1 3