我该如何预取小矮人?

问题描述 投票:0回答:2

我正在尝试进行优化的SQL查询,以检索对象A的列表,对象A的列表包含对象B的列表,对象B的列表包含对象C和D的列表以及与E的多对多关系

我已经尝试解决聚合行的问题,但是当没有类型B或C或D的对象时出现问题。

例如,我尝试过此查询:

aa = A.alias()
query = (A.select(A, B, aa, C, D, E).join(B, peewee.JOIN_LEFT_OUTER).join(aa, peewee.JOIN_LEFT_OUTER).switch(B).join(C, peewee.JOIN_LEFT_OUTER).switch(B).join(D, peewee.JOIN.LEFT_OUTER).switch(B).join(E, peewee.JOIN_LEFT_OUTER))

然后,我使用aggregate_rows对数据进行重复数据删除。当有B,C和D的行时它起作用,但是当没有行时,我没有得到带有B或C或D空列表的相应A对象。

[我也尝试过使用预取,但是当我访问A.B peewee时不运行查询(良好),但是当我访问A.B.C peewee时运行查询(错误)。

A_objects = peewee.prefetch(A,B,C,D,E)

我迷路了,我不知道我在做什么错。

python orm peewee
2个回答
0
投票

[天哪,这有很多关系。您是否已经分析了代码,并且确定预取将大大缩短加载时间?您的示例中最外面的循环(A)是否是一个很大的列表?我建议在尝试“优化”您的查询之前先进行深入研究。

aggregate_rows()

听起来像您在Peewee 2.x上吗?这已经很老了,已经无法维护了。在3.x中删除了此方法,因为它在99%的情况下效率非常低。

以及与E的多对多关系

这可能是问题所在。实际上,多对多表是2个表-一个具有两个外键的联结表,一个用于源对象,一个用于目的对象的表在多对多关系中。因此,如果要尝试跨多对多预取,则需要包括联结表。这可能会很复杂。

您可以在测试中看到一些如何在多对多中预取的示例:

https://github.com/coleifer/peewee/blob/7bfe65cd3689e7bbd0ad5345c0454cba1b559b94/tests/manytomany.py#L278-L308


0
投票

最后,我找到了解决方案。正如coleifer告诉我的那样,正如我在文档中阅读的那样,继续进行操作而不是aggregate_rows的方法是预取。在Versión中,我在提出问题之前是2.x。该版本使用后缀_prefetch提取预取数据。例如,如果A具有属性A.something,则在我们预取它时,它将在A.something_prefetch中恢复。棉花糖直接与我们的模型对话。这意味着,当它想要获取A.something时,它将查询A.something而不是A.something_prefetch。peewee 2.x中的A.something是一个SelectQuery对象,因此它将进行SQL查询而不是恢复预取的数据。

最后,我已经将peewee的版本升级到3.x,现在可以使用了。我不知道coleifer是否可以告诉我们这个答案是否正确,但现在可以了。

希望有帮助!。>

© www.soinside.com 2019 - 2024. All rights reserved.