Код: Выделить всё
BadRequestError: cursor position is outside the range of the original query
Мое приложение обрабатывает элементы. У каждого элемента есть владелец и строка даты.
Он выполняется в двух частях: сначала проверяются существующие элементы (из предыдущих запусков), сравниваются их с ранее сохраненными в NDB (устанавливается строка даты). После этого он обрабатывает все один раз без обновления дат; с помощью функции full_run.
Код: Выделить всё
#runs as a deferred task
def full_run(ownerKey, run_date):
query = Item.query(ndb.AND(
Item.owner == ownerKey,
ndb.OR(Item.push_date < run_date, Item.push_date > run_date)
)).order(Item.push_date, Item._key)
more = True
curs = None
while more:
ndb_keys, curs, more = query.fetch_page(page_size=1000, start_cursor=curs, keys_only=True)
deferred.defer(handle_key_page, ndb_keys, run_date)
def handle_key_page(key_page, run_date):
for item in ndb.get_multi(key_page):
deferred.defer(do_stuff, item)
item.push_date = run_date
item.put()
При изменении элемента запроса курсор страницы становится недействительным.
Это обходное решение использует это задачи перезапускаются при возникновении ошибок. При новом запуске будет получен новый набор из 1000 записей (макс.:page_size), поскольку обновленные элементы будут исключены из будущих запросов.
Две проблемы стали до боли очевидными:< /p>
¤ Задачи имеют экспоненциальную задержку, поэтому время, необходимое для завершения, увеличивается в геометрической прогрессии. (сложно отлаживать)
¤ Я обрабатываю ошибки (в do_stuff), сбрасывая дату. Сначала я подумал об этом как о незначительной проблеме, поскольку считал, что это нормально, если несколько элементов из 1000 обрабатываются несколько раз.
В совокупности эти два фактора делают это решение менее масштабируемым, чем Я бы хотел, чтобы так и было, но лучшего решения я не нашел.
Подробнее здесь: https://stackoverflow.com/questions/402 ... de-the-ran