Задача Chaining with Cursor выдает проблему в движке приложения.Исключение: слишком большое смещение запроса.Кто-нибудь еще получил эту проблему? - PullRequest
2 голосов
/ 15 августа 2010

Я не уверен, что у кого-то еще есть эта проблема, но я получаю исключение "Слишком большое смещение запроса" при использовании курсора для цепочки задач на сервере разработки appengine (не уверен, что это бывает вживую).

Ошибка возникает при запросе курсора после того, как 4000+ записей были обработаны в одном запросе.

Я не знал, что смещения имеют какое-то отношение к курсорам, и, возможно, это просто причуда в sdk для движка приложений.

Чтобы исправить, либо сократите время, отведенное до того, как задача будет отложена (чтобы за один раз обрабатывалось меньше записей), либо по истечении времени проверки вы также можете проверить, что количество обработанных записей все еще находится в пределах диапазона. например, если time.time ()> end_time или count == 2000 . Сбросить счет и отложить задачу. 2000 - произвольное число, я не уверен, каким должен быть предел.

EDIT:

После внесения вышеупомянутых изменений выполнение никогда не завершается. Код with_cursor (курсор) вызывается, но, кажется, каждый раз начинается с начала. Я что-то упускаю из виду?

Код, который вызывает , исключение выглядит следующим образом:

Таблица "Транзакция" имеет 4800 строк. Ошибка возникает, когда transacts.cursor () вызывается, когда time.time ()> end_time имеет значение true. 4510 записей были обработаны в тот момент, когда запрашивается курсор, что, по-видимому, и вызывает ошибку (на сервере разработки не тестировался в других местах).

def some_task(trans):
  tts = db.get(trans)
  for t in tts:
    #logging.info('in some_task')
    pass


def test_cursor(request):
  ret = test_cursor_task()


def test_cursor_task(cursor = None):
  startDate = datetime.datetime(2010,7,30)
  endDate = datetime.datetime(2010,8,30)
  end_time = time.time() + 20.0   
  transacts = Transact.all().filter('transactionDate >', startDate).filter('transactionDate <=',endDate)

  count =0
  if cursor:
      transacts.with_cursor(cursor)
  trans =[]
  logging.info('queue_trans')
  for tran in transacts:
    count+=1
    #trans.append(str(tran))   
    trans.append(str(tran.key()))   

    if len(trans)==20:
            deferred.defer(some_task, trans,  _countdown = 500)                
            trans =[]            
    if time.time() > end_time:
        logging.info(count)            
        if len(trans)>0:                
           deferred.defer(some_task, trans, _countdown = 500)
           trans =[]
        logging.info('time limit exceeded setting next call to queue')
        cursor = transacts.cursor()
        deferred.defer(test_cursor_task, cursor)
        logging.info('returning false')
        return False


    return True


  return HttpResponse('')

Надеюсь, это кому-нибудь поможет.

Спасибо Bert

1 Ответ

1 голос
/ 28 февраля 2012

Попробуйте еще раз, не используя функциональность iter :

#...
CHUNK = 500
objs = transacts.fetch(CHUNK)

for tran in objs:
    do_your_stuff

if len(objs) == CHUNK:
    deferred.defer(my_task_again, cursor=str(transacts.cursor()))

Это работает для меня.

...