繁体   English   中英

Peewee在内部联接期间返回多个对象

[英]Peewee returns multiple Objects during an Inner Join

class Parent(BaseModel):
    name = peewee.CharField()

class Child(BaseModel):
    name = peewee.CharField()
    parent = peewee.ForeignKeyField(Parent, related_name='children')

parent = Parent.create(name="Parent1")
child1 = Child.create(name="Child1", parent=parent)
chilld2 = Child.create(name="Child2", parent=parent)

query = (Parent.select()
        .join(Child))

for p in query:
    print p.name
    for c in p.children:
        print "\t",c.name

结果为以下输出:

Parent1
    Child1
    Child2
Parent1
    Child1
    Child2

我被期望这样:

Parent1
    Child1
    Child2

似乎我正在遍历一个SQL结果集,而不是ORM意义上的一个对象。 从ORM角度来看,假设查询中只有一个“父对象”,如何修改查询或对该查询的迭代以获得预期结果?

我想像在peewee示例应用程序中一样将查询返回到我的模板,并对其进行迭代以显示对象,但是如果这样做,它将显示同一对象两次(对于n个相关子对象,则显示n次)。

我知道我可以执行以下操作:

p = query.get()
print p.name
for c in p.children:
    print "\t", c.name

但是,当我有多个父母并且只想遍历所有父母时,我无法确定有多少父母。 查询的count方法返回结果集的计数,而不是结果集的计数。

这也可以解决:

pars = []
for p in query:
    if p not in pars:
        pars.append(p)

for p in pars:
    print p.name
    for c in p.children:
        print "\t", c.name

您的代码有两个问题。

首先是,即使您已加入Child ,调用parent.children也会执行一个额外的单独查询。

由于第一个问题,您误解了外部循环的作用,这只是给您Parent1 + Child1的Parent部分,Parent1 + Child2。

要解决此问题,您可以使用prefetchaggregate_rows

# Execute a single query and de-dupe the duplicated parent rows.
query = Parent.select(Parent, Child).join(Child).aggregate_rows()
for parent in query:
    print parent.name
    for child in parent.children:
        print childname

# Execute a query for each joined table. Generally more efficient
# than aggregate_rows().
query = prefetch(Parent.select(), Child)
for parent in query:
    print parent.name
    for child in parent.children_prefetch:  # NOTE the `_prefetch`
        print child.name

对此进行了广泛的记录: http : //docs.peewee-orm.com/en/latest/peewee/querying.html#avoiding-n-1-queries

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM