过期查询与App Engine
在一个任务中,我正在通过查询来遍历一组项目。在从查询中获取每个实体后,我还会进行一个网址请求。在处理了很多这些项目后,我遇到了以下错误:
BadRequestError: The requested query has expired. Please restart it with the last cursor to read more results.
一旦你创建了查询,它的租约是什么?
3 个回答
0
简单来说,就是为你序列中的每个元素创建延迟任务。这里有一篇不错的文章,里面有很多例子,教你怎么正确地做到这一点,链接在这里:“使用延迟库进行后台工作”。
1
我写了一个简单的助手来完成这个任务——你只需要传入批量大小、查询的对象类,以及处理查询结果的回调函数。
(注意,我使用的是djangoappengine,所以用的是django的查询格式——不过你可以根据需要进行修改。)
def loop_over_objects_in_batches(batch_size, object_class, callback):
logging.info("Calling batched loop with batch_size: %d, object_class: %s, callback: %s" % (batch_size, object_class, callback))
num_els = object_class.objects.all().count()
num_loops = num_els / batch_size
remainder = num_els - num_loops * batch_size
offset = 0
while offset < num_loops * batch_size:
logging.info("Processing batch (%d:%d)" % (offset, offset+batch_size))
query = object_class.objects.all()[offset:offset + batch_size]
for q in query:
callback(q)
offset = offset + batch_size
if remainder:
logging.info("Processing remainder batch (%d:-)" % offset)
query = object_class.objects.all()[offset:]
for q in query:
callback(q)
7
这个问题可能会对你的困扰有所帮助:https://code.google.com/p/googleappengine/issues/detail?id=4432
虽然现在离线请求可以持续最多10分钟(而后台实例可以一直运行),但数据存储的查询仍然只能持续30秒。我们计划改进这个问题,但由于数据的一致性视图只能保持有限的时间,所以查询的持续时间是有上限的(少于10分钟)。
...
与其进行一次很长的查询,不如考虑使用查询游标分批获取数据。