Skip to main content
 首页 » 编程设计

python之App Engine 上带有 Cursor 问题的任务链接。异常 : Too big query offset. 还有其他人遇到这个问题吗

2025年05月04日26开发

我不确定其他人是否有这个问题,但是当我在应用引擎开发服务器上使用游标链接任务时,我得到了一个异常“查询偏移量太大”(不确定是否它发生在现场)。

在单个查询中处理了 4000 多条记录后请求游标时发生错误。

我不知道偏移量与游标有任何关系,也许它只是 app engine 的 sdk 中的一个怪癖。

要修复,要么缩短任务延迟前允许的时间(这样一次处理的记录就会减少),要么在检查时间过去时,您还可以检查处理的记录数是否仍在范围内。例如,如果 time.time() > end_time 或 count == 2000。重置计数并延迟任务。 2000 是一个任意数字,我不确定该限制应该是多少。

编辑:

进行上述更改后,永远不会完成执行。正在调用 with_cursor(cursor) 代码,但似乎每次都从头开始。我是否遗漏了一些明显的东西?

导致异常的代码如下:

“交易”表有 4800 行。当 time.time() > end_time 为真时调用 transacts.cursor() 时会发生错误。 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('') 

希望这对某人有帮助。

谢谢 伯特

请您参考如下方法:

在不使用 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())) 

这对我有用。