【问题标题】:python traverse CTE in a double for loop?python在双for循环中遍历CTE?
【发布时间】:2017-04-15 16:46:43
【问题描述】:

我有 2 个相互之间的 for 循环。对于loop1中的每一行'A'、'B'、'C',我需要访问分层树以在loop2中找到组'X'的所有父级。这使我在需要分别找到每一行的路径的地方使用 CTE。在循环中使用 CTE 并不是确定我可以在哪里匹配每个组 id 的解决方案。引用了这个链接,但看不懂Looping hierarchy CTE

使用flask框架的cron作业的代码sn-p:

    s = select([rt_issues]).\
    where(
        and_(
            rt_issues.c.status !='Closed',
            rt_issues.c.assigned_to != None
        ))
rs = conn.execute(s)
if rs.rowcount > 0:
    s4 = text('with recursive rec_grp as(select id, parent_id, name, head, 1 as level, array[id] as path_info from groups union all select grp1.id, grp1.parent_id, grp1.name, grp1.head, rc.level + 1, rc.path_info||grp1.id from groups grp1 join rec_grp rc on grp1.id = rc.parent_id) select distinct id, parent_id, name, head, path_info from rec_grp order by id')

    rs4 = conn.execute(s4)

    for r in rs:
        head_list = []
        hierarchical_grps = []
        for rr in rs4:
            if ((rr['path_info'][0] == r[rt_issues.c.assignee_group])):
                for g in rr['path_info']:
                    hierarchical_grps.append(g)
        hierarchical_grps = list(set(hierarchical_grps))            
        send_pending_mail(hierarchical_grps, r['id'])
        print hierarchical_grps, 'hierarchical_grps'

    exit(0)

我需要向问题层次结构中assignee_group 的所有组长发送邮件。这怎么可能实现。如何正确使用循环?我只使用 sqlalchemy 核心、postgresql、python 和烧瓶。我需要相同的确切代码。

下面的 sn-p 有效:

 mgroup = None
 s = select([rt_issues]).\
     where(
         and_(
             rt_issues.c.status !='Closed',
             rt_issues.c.assigned_to != None
         ))
 rs = conn.execute(s)
 if rs.rowcount > 0:
     for r in rs:
         head_list = []
         hierarchical_grps = []
         mgroup = r[rt_issues.c.assignee_group]
         s4 = text('with recursive rec_grp as(select id, parent_id, name, head, 1 as level, array[id] as path_info from groups where id=' +str(mgroup) + 'union all select grp1.id, grp1.parent_id, grp1.name, grp1.head, rc.level + 1, rc.path_info||grp1.id from groupsgrp1 join rec_grp rc on grp1.id = rc.parent_id) select distinct id,parent_id, name, head, path_info from rec_grp order by id')

     rs4 = conn.execute(s4)
     for rr in rs4:
         if ((rr['path_info'][0] == r[rt_issues.c.assignee_group])):
             for g in rr['path_info']:
                 hierarchical_grps.append(g)
     hierarchical_grps = list(set(hierarchical_grps))
     print hierarchical_grps, 'hierarchical_grps'
     send_pending_mail(hierarchical_grps, r['id'])
 exit(0)

【问题讨论】:

标签: python postgresql flask sqlalchemy common-table-expression


【解决方案1】:

假设head 列是布尔值,这将收集设置了head 标志的组:

rs4 = con.execute(s4)
for rr in rs4:
    if rr['head']:
        head_list.append(rr['id'])

print 'group heads:', head_list

这是假设使用第二个示例中的查询(注意对 from 子句的更正,“from groupsgrp1”应该是“from groups grp1”):

WITH RECURSIVE rec_grp AS (
  SELECT
    id,
    parent_id,
    name,
    head,
    1          AS level,
    ARRAY [id] AS path_info
  FROM groups
  WHERE id = 4
  UNION ALL
  SELECT
    grp1.id,
    grp1.parent_id,
    grp1.name,
    grp1.head,
    rc.level + 1,
    rc.path_info || grp1.id
  FROM groups grp1
    JOIN rec_grp rc ON grp1.id = rc.parent_id
)
SELECT DISTINCT
  id,
  parent_id,
  name,
  head,
  path_info
FROM rec_grp
ORDER BY id;

【讨论】:

  • 您只使用了一个特定的 ID。我想要的是一个 id 列表。
  • 这会列出问题组中设置了head 标志的所有父组。您需要针对多个问题还是单个问题的列表?
  • 针对多个问题。是否有必要为每个匹配的问题一直执行 CTE? -这可以避免吗?我想知道如果按照我所说的那样执行对性能的影响。有没有更好的选择是我正在寻找的
  • 您关心问题的数量,还是群组的数量?最简单的方法是一次遍历一个问题,每次都将层次结构展平。在它成为问题之前我不会担心性能(premature optimization is the root of all evil 等)。我怀疑您的邮件流程将成为瓶颈,而不是邮件列表的解决方案。
猜你喜欢
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 2021-04-01
  • 2018-08-02
  • 2016-03-03
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
相关资源
最近更新 更多