这两段代码有什么区别?
query=Location.all(keys_only=True)
while query.count()>0:
db.delete(query.fetch(5))
# --
while True:
query=Location.all(keys_only=True)
if not query.count():
break
db.delete(query.fetch(5))
他们都工作。
答案 0 :(得分:6)
逻辑上,这两段代码执行完全相同的操作 - 它们一次删除每个Location
实体。
第一段代码在风格方面和(略微)在性能方面都更好。 (查询本身不需要在每个循环中重建。)
但是,此代码效率不高。它有几个问题:
您使用count()
但不需要。简单地获取实体,然后测试结果以查看是否有任何实体会更有效。
您正在向数据存储区进行更多往返行程。每个count()
,fetch()
和delete()
调用都必须转到数据存储区并返回。这些往返很慢,所以你应该尽量减少它们。您可以通过在每个循环中获取更多实体来完成此操作。
示例:
q = Location.all(keys_only=True)
results = q.fetch(500)
while results:
db.delete(results)
results = q.fetch(500)
编辑:看一下Nick的答案 - 他解释了为什么使用查询游标可以进一步提高代码的性能。
答案 1 :(得分:2)
这是一个更整洁的解决方案,但您可能会或可能不会考虑成为黑客:
q = Location.all(keys_only=True)
for batch in iter(lambda: q.fetch(500), []):
db.delete(batch)
然而,一个问题是,随着您删除越来越多,后端被迫跳过“逻辑删除”实体以查找未删除的下一个实体。这是一个使用游标的更有效的解决方案:
q = Location.all(keys_only=True)
results = q.fetch(500)
while results:
db.delete(results)
q = Location.all(keys_only=True).with_cursor(q.cursor())
results = q.fetch(500)
答案 2 :(得分:0)
在第二个中,query
将在每个循环中分配/更新。我不知道这背后的逻辑是否需要它(我不使用谷歌应用程序引擎)。要复制此行为,第一个行为必须如下所示:
query=Location.all(keys_only=True)
while query.count()>0:
db.delete(query.fetch(5))
query=Location.all(keys_only=True)
在我看来,第一种风格比第二种风格更具可读性。
答案 3 :(得分:0)
太糟糕了,你不能在python中做到这一点。
query=Location.all(keys_only=True)
while locations=query.fetch(5):
db.delete(locations)
与其他P语言一样
while(@row=$sth->fetchrow_array){
do_something();
}