カーソルを使用してデータストアにクエリを実行する必要があります (タスクが 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 です)。2 番目のループ (カーソルが初期化される) で、エラーが発生します。私もイテレータでこれをやろうとしました:
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 を 2 つの個別のクエリに分割する作業を行っています。それでも、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)