Google App Engine - 删除直到count()< = 0

时间:2010-06-13 23:38:49

标签: google-app-engine

这两段代码有什么区别?

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))

他们都工作。

4 个答案:

答案 0 :(得分:6)

逻辑上,这两段代码执行完全相同的操作 - 它们一次删除每个Location实体。

第一段代码在风格方面和(略微)在性能方面都更好。 (查询本身不需要在每个循环中重建。)

但是,此代码效率不高。它有几个问题:

  1. 您使用count()但不需要。简单地获取实体,然后测试结果以查看是否有任何实体会更有效。

  2. 您正在向数据存储区进行更多往返行程。每个count()fetch()delete()调用都必须转到数据存储区并返回。这些往返很慢,所以你应该尽量减少它们。您可以通过在每个循环中获取更多实体来完成此操作。

  3. 示例:

    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();
}