如何在Peewee的树表查询中避免“ N + 1行为”?

时间:2019-02-07 01:39:23

标签: python peewee

我有一个由父链接外键表示的树型数据结构,我想使用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

1 个答案:

答案 0 :(得分: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