【问题标题】:How to avoid a "N+1 behavior" in a tree table query in Peewee?如何在 Peewee 的树表查询中避免“N+1 行为”?
【发布时间】:2019-02-07 01:39:23
【问题描述】:

我有一个由父链接外键表示的树数据结构,我想使用 backref 避免 Peewee 每次都执行新查询。

我使用的模型是这样的:

from peewee import *

class Table(Model):
    name = TextField()
    parent = ForeignKeyField('self', null=True, backref='children')

Table.create_table()

root = Table.create(name="root", parent=None)
A1 = Table.create(name="A1", parent=root)
A2 = Table.create(name="A2", parent=root)
B1 = Table.create(name="B1", parent=A1)

我需要从某个元素中获取包含所有子三项的字典。

我试试这个:

query = Table.select().where(Table.name == "root")
tree = [model_to_dict(a, backrefs=True, recurse=True) for a in query]

我明白了:

[{
    'id': 1,
    'name': 'root',
    'parent': None,
    'children': [
        {'id': 2,'name': 'A1'},
        {'id': 3,'name': 'A2'}
    ]
}]

但它有两个问题:1)它只给了我所有后代树的直接子代。 2) 它多次访问数据库。

有什么方法可以得到完整的子树而不会出现 N+1 问题http://docs.peewee-orm.com/en/latest/peewee/relationships.html#nplusone

【问题讨论】:

    标签: python peewee


    【解决方案1】:

    您唯一真正的选择是使用递归公用表表达式。文档中有一个部分可能会有所帮助,因为它完全处理这种类型的查询:

    http://docs.peewee-orm.com/en/latest/peewee/querying.html#recursive-ctes

    查询示例也有递归 CTE 示例:

    http://docs.peewee-orm.com/en/latest/peewee/query_examples.html#find-the-upward-recommendation-chain-for-member-id-27

    【讨论】:

    • 我试过了。但是我还没有设法获得嵌套字典。我想我可以使用递归 CTE 来获取所有后代,然后将结果转换为嵌套字典,但我认为 Peewee 可以以更优雅的方式做到这一点。
    • 数据库游标返回行元组。任何递归 CTE 仍然只会产生一个扁平元组列表。数据库不是分层的——它们是关系的。任何层次结构的转换都需要您自己完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多