Python 在从数据存储查询返回列表方面,fetch()比list(Model.all().run())好吗?

Python 在从数据存储查询返回列表方面,fetch()比list(Model.all().run())好吗?,python,google-app-engine,python-2.7,Python,Google App Engine,Python 2.7,使用Google App Engine Python 2.7查询类- 我需要生成一个结果列表,并将其传递给django模板。我发现有两种方法可以做到这一点 使用fetch,但是在文档中它说fetch几乎不应该被使用 使用run()并将其包装到list()中,从而创建list对象 就内存使用而言,一个比另一个更可取吗?还有其他方法可以这样做吗?这里的关键是为什么fetch几乎不应该被使用。文档中说,fetch将获得所有结果,因此必须同时将所有结果保存在内存中。如果你得到的数据很大,你将需要大量的内

使用Google App Engine Python 2.7查询类-

我需要生成一个结果列表,并将其传递给django模板。我发现有两种方法可以做到这一点

  • 使用fetch,但是在文档中它说fetch几乎不应该被使用

  • 使用run()并将其包装到list()中,从而创建list对象

  • 就内存使用而言,一个比另一个更可取吗?还有其他方法可以这样做吗?

    这里的关键是为什么
    fetch
    几乎不应该被使用。文档中说,
    fetch
    将获得所有结果,因此必须同时将所有结果保存在内存中。如果你得到的数据很大,你将需要大量的内存

    您说您可以将
    运行
    包装在
    列表
    中。当然,您可以这样做,但您将遇到完全相同的问题-
    list
    将强制所有元素进入内存。因此,这种解决方案实际上与使用
    fetch
    一样不受欢迎

    现在,你可以说:那我该怎么办?答案是:在大多数情况下,您可以一个接一个地处理数据元素,而无需将它们同时保存在内存中。例如,如果您只需要将结果数据放入django模板中,并且您知道它在模板中最多使用一次,那么django模板将很乐意使用任何迭代器,这样您就可以直接传递
    运行
    调用结果,而无需将其包装到
    列表

    类似地,如果您需要进行一些处理,例如,检查结果以查找具有最高价格或排名的元素,或者其他任何内容,您可以迭代
    run
    的结果


    但是,如果您的使用需要将所有元素都存储在内存中(例如:django模板多次使用查询中的数据),那么您就有了一种情况,即
    fetch
    list(run(…)
    实际上是有意义的。最后,这只是一个典型的权衡:如果您的应用程序需要应用一个算法,该算法需要内存中的所有数据,那么您需要通过耗尽内存来支付。因此,您可以重新设计算法和用法以使用迭代器,或者使用
    fetch
    并通过更长的处理时间和更高的内存使用率来支付费用。谷歌当然鼓励你做第一件事。这就是“几乎永远不应该被使用”的真正含义。

    谢谢你的回答——我一定是对Django做了错事。上次我尝试将迭代器传递给它时,我记得我认为它犹豫了,需要一个实际的列表。我将回到django如何从{%for object in itr%}重新处理它,在这里,itr是从itr=Model.all()传递的。run()@DanielYoung:记住,迭代器在内存中的便宜之处在于它们只能一次使用。您不能在django模板的两个位置使用这样的迭代器两次,或者在代码中使用一次,然后在django模板中使用。这可能是你认为它“停滞不前”的原因。我真的很感谢你的帮助和你清晰简洁的回答。还有一个问题,与我现在所做的相比,两次生成相同的迭代器是否有利?无论哪种方式,都需要对算法进行返工。@DanielYoung:根据我的经验,将其保存在内存中几乎总是最好的选择——一两兆字节的内存并不多,在web应用程序中,很少在单个页面视图中处理更多的数据。但这取决于大小和查询处理成本。我的建议是,如果您知道修改算法以接受迭代器将需要更多的时间使用更简单的算法(可能使用
    fetch
    ),并且只有当您在效率方面确实存在问题时才对其进行优化。非常感谢-我将尝试一下。