如何使用Python从Postgresql中的嵌套CTE输出嵌套json?

时间:2019-03-19 15:58:27

标签: python sqlalchemy

使用sqlalchemy核心定义的表:

categories = Table("categories", metadata,
                   Column("id", Integer, primary_key=True),
                   Column("name", String),
                   Column("parent_id", Integer, 
                          ForeignKey("categories.id"),
                   Column("dept_id", Integer, 
                          ForeignKey("departments.id"),
                          CheckConstraint('id!=parent_id'), 
                          nullable=True),
                   UniqueConstraint('parent_id','name', 
                   name='parent_category'))

预期o / p:

{"id": 1,
"parent_id": null,
"name": "root",
"dept_id": null,
   children:[
   {id": 2, "parent_id": 1, "name": "Top_level", "dept_id": null},
   {"id": 3, "parent_id": 1, "name": "Rt_Docs", "dept_id": null}}
   ]
}]

我尝试使用sqlalchemy的内容:

s = text('具有递归rec_cat as(选择id,parent_id,名称,dept_id,0作为级别,array [id]作为path_info),其中parent_id为null的类别都选择了cat1.id,cat1.parent_id,cat1 .name,cat1.dept_id,级别+ 1,来自rec_cat p的path_info || cat1.parent_id加入cat1.parent_id = p.id上的类别cat1,其中cat1.id = any(path_info)除外,dncc为(选择cat1.parent_id ,json_agg(jsonb_build_object(\'Name \',cat1.name)):: jsonb作为来自rec_cat树的js,使用(id)结合类别cat1,其中级别> 0而不是id = any(path_info)由cat1.parent_id联合所有从dncc树连接目录中选择cat1.parent_id,jsonb_build_object(\'Name \',cat1.name)|| jsonb_build_object(\'Sub-cat \',js)作为cat加入cat1.id = tree.parent_id上的类别cat1选择jsonb_agg (js)来自dncc,其中parent_id为null')

cat_list = []
mdept_id = None
rs = g.conn.execute(s)
for r in rs:
    mx = collections.OrderedDict(r)
    cat_list.append(mx)
#print cat_list, 'cat_list'
return jsonify({'cat_list': cat_list}), 200

我正在获取输出,但不是“所需的”层次嵌套格式。它给出了结果,但是在每个级别之后将给出完整的树,其中包含子类别,如链接中所示。 Pl。建议我需要进行哪些更改才能以上述格式获得o / p。我尝试了以下链接:enter link description here

上面的结果是:

cat_list": [
    {
      "jsonb_agg": [
        {
          "Name": "root", 
          "Sub-cat": [
            {
              "Name": "dne-mount"
            }, 
            {
              "Name": "dne-mktg"
            }, 
            {
              "Name": "Marketing"
            }, 
            {
              "Name": "Top_level"
            }, 
            {
              "Name": "Rt_Docs"
            }
          ]
        }, 
        {
          "Name": "root", 
          "Sub-cat": {
            "Name": "Top_level", 
            "Sub-cat": [
              {
                "Name": "Cat1"
              }
            ]

即。不嵌套列表

1 个答案:

答案 0 :(得分:0)

使其正常工作,我的sql中出现错误:

s = text('with recursive rec_cat as(select id, parent_id, name, dept_id, 0 as level, array[id] as path_info from categories where parent_id is null union all select cat1.id, cat1.parent_id, cat1.name, cat1.dept_id, level + 1, path_info||cat1.parent_id from rec_cat p join categories cat1 on cat1.parent_id=p.id where not cat1.id= any(path_info)), dncc as (select cat1.parent_id, json_agg(jsonb_build_object(\'Name\',cat1.name))::jsonb as js from rec_cat tree join categories cat1 using (id)  where level > 0 and not id=any(path_info) group by cat1.parent_id union all select cat1.parent_id, jsonb_build_object(\'Name\', cat1.name) || jsonb_build_object(\'Subclasses\', js) as js from dncc tree join categories cat1 on cat1.id=tree.parent_id) select jsonb_agg(js) from dncc where parent_id is null')