gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 04:47:54 26 4
gpt4 key购买 nike

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 次相关子对象) )。

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

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

但是当我有多个 parent 并且只想遍历所有 parent 时,我无法确定有多少个 parent 。查询的 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、Parent1+Child2 的 Parent 部分。

要解决此问题,您可以使用 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

关于python - Peewee 在内部联接期间返回多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29045154/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com