过期查询与App Engine

10 投票
3 回答
1543 浏览
提问于 2025-04-17 02:30

在一个任务中,我正在通过查询来遍历一组项目。在从查询中获取每个实体后,我还会进行一个网址请求。在处理了很多这些项目后,我遇到了以下错误:

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分钟)。

...

与其进行一次很长的查询,不如考虑使用查询游标分批获取数据。

撰写回答