如何为查询中的每个基础行获取单独的结果?

时间:2018-01-08 14:43:14

标签: python sqlalchemy

我有一个这样的模型:

Category:
    id (primary key)
    parent_id (foreign key)
    name (string)

并且有一个子类别id的列表,我正在使用sqlalchemy公共表表达式递归查询他们的父母:

r = session.query(Category.id, Category.parent_id, *fields).\
    filter(Category.id.in_(id_list)).\
        cte(name='r', recursive=True)
r_alias = aliased(r, name="recursive")
base_alias = aliased(Category, name='base')
included_parts = r.union_all(
  session.query(base_alias).filter(base_alias.id == r_alias.c.parent_id)
)
q = session.query(included_parts).all()
print(q)

这产生了以下结果(所有具有id' s [1,2]的类别的父母:

[(1, None, 'Category1'), (2, 1, 'Category2'), (1, None, 'Category1')]

但我想单独列出每个类别的列表,我需要的是这样的事情(id_list中每个id的单独结果):

[
    [(1, None, 'Category1')],
    [(2, 1, 'Category2'), (1, None, 'Category1')]
]

有没有办法做到这一点或使组更容易分离(例如,是否有一种方法可以在每个结果中包含id_list中的相应id,以便我可以通过它对结果进行分组)SQLAlchemy意味着什么?< / p>

例如,如何获得以下结果而不是我得到的结果:

[(1, 1, None, 'Category1'), (2, 2, 1, 'Category2'), (2, 1, None, 'Category1')]

然后我可以通过每个元组的第一个成员对它们进行分组以获得所需的组。

1 个答案:

答案 0 :(得分:1)

简单的解决方案是将原始ID添加为原始SELECT中的第一列,并在递归CTE的迭代步骤中继续选择它们:

In [18]: r = session.query(Category.id.label('orig_id'),
    ...:                   Category.id,
    ...:                   Category.parent_id,
    ...:                   *fields).\
    ...:     filter(Category.id.in_(id_list)).\
    ...:     cte(name='r', recursive=True)
    ...: 
    ...: r_alias = aliased(r, name="recursive")
    ...: base_alias = aliased(Category, name='base')
    ...: 
    ...: included_parts = r.union_all(
    ...:   session.query(r_alias.c.orig_id,  # Select the originating ID here
    ...:                 base_alias).
    ...:       filter(base_alias.id == r_alias.c.parent_id))
    ...:       
    ...: res = session.query(included_parts).all()
    ...: print(res)
    ...: 
[(1, 1, None, 'first'), (2, 2, 1, 'second'), (2, 1, None, 'first')]