我需要使用游标查询数据存储区(我需要游标,因为任务可能无法在10分钟内完成)。到目前为止,我无法使用fetch_page或Query.iter()获取有效的游标。在这两种情况下,当我使用生成的光标时,我得到了一个
BadRequestError:光标位置超出原始范围 查询
这是查询
qry = entity_type.query(ndb.AND(entity_type.application == "my_app",
ndb.OR(entity_type.status == 1,
ndb.AND(entity_type.status == 0,
entity_type.date >= start_date,
entity_type.date < end_date))))
qry = qry.order(entity_type.date, entity_type._key)
请注意,我使用ndb.OR进行过滤,并且我还按照在线文档中的说明对模型的密钥进行排序。
运行查询的代码非常简单
cursor = None
has_more = True
while has_more:
entities, cursor, more = qry.fetch_page(500,
start_cursor=cursor,
use_cache=False,
use_memcache=False)
# process the retrieved entities
has_more = cursor and more
第一个循环正常(光标为None)。在第二个循环(游标初始化),我得到错误。我也试过用迭代器做这个:
cursor = None
has_more = True
while has_more:
q_options = {"use_cache": False,
"use_memcache": False,
"produce_cursors": True}
if cursor is not None:
q_options["start_cursor"] = cursor
q_iter = qry.iter(**q_options)
entities = []
for e in q_iter:
entities.append(e)
if len(entities) == 500:
break
more = q_iter.has_next()
if more:
cursor = q_iter.cursor_after()
# process the retrieved entities
has_more = cursor and more
我看到了同样的行为。我目前正在努力将ndb.OR分解为两个单独的查询。然而,我想知道我是否滥用了ndb API,还是其他什么?
- 更新 - 这是错误的跟踪
W 05:00:09.171 suspended generator run_to_queue(query.py:938) raised BadRequestError(cursor position is outside the range of the original query)
W 05:00:09.762 suspended generator run_to_queue(query.py:1946) raised BadRequestError(cursor position is outside the range of the original query)
W 05:00:09.762 suspended generator run_to_queue(query.py:931) raised BadRequestError(cursor position is outside the range of the original query)
W 05:00:09.762 suspended generator helper(context.py:876) raised BadRequestError(cursor position is outside the range of the original query)
W 05:00:09.762 suspended generator has_next_async(query.py:1745) raised BadRequestError(cursor position is outside the range of the original query)
W 05:00:09.777 suspended generator _fetch_page_async(query.py:1349) raised BadRequestError(cursor position is outside the range of the original query)
E 05:00:09.777 cursor position is outside the range of the original query
Traceback (most recent call last):
[... some of my classes ...]
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/utils.py", line 142, in positional_wrapper
return wrapped(*args, **kwds)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 1331, in fetch_page
return self.fetch_page_async(page_size, **q_options).get_result()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 325, in get_result
self.check_success()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
value = gen.throw(exc.__class__, exc, tb)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 1349, in _fetch_page_async
while (yield it.has_next_async()):
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
value = gen.throw(exc.__class__, exc, tb)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 1745, in has_next_async
yield self._fut
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/context.py", line 876, in helper
batch, i, ent = yield inq.getq()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 931, in run_to_queue
yield multiquery.run_to_queue(queue, conn, options=options)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
value = gen.throw(exc.__class__, exc, tb)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 1946, in run_to_queue
thing = yield subit.getq()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/query.py", line 938, in run_to_queue
batch = yield rpc
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 454, in _on_rpc_completion
result = rpc.get_result()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
return self.__get_result_hook(self)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/datastore/datastore_query.py", line 2973, in __query_result_hook
self._batch_shared.conn.check_rpc_success(rpc)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1342, in check_rpc_success
raise _ToDatastoreError(err)
BadRequestError: cursor position is outside the range of the original query
W 05:00:10.040 Found 1 RPC request(s) without matching response (presumably due to timeouts or other errors)