这是将类型的所有实体导出到csv文件的好方法吗?

时间:2012-07-11 14:34:07

标签: python google-app-engine

我有数百万个特定类型的实体,我想将其导出到csv文件。以下代码将批量为1000的实体写入blob,同时保持blob打开并将下一批次推迟到任务队列。当没有更多实体被提取时,blob被最终确定。这似乎适用于我当地的大多数测试,但我想知道:

如果我在生产数据上运行任何陷阱或角落案件之前错过了,并且因为数据存储读取而产生$ s。

如果在批处理写入blob时超出截止日期或内存耗尽,则此代码默认为当前批处理的开始,以便再次运行任务,这可能会导致大量重复。有什么建议可以解决这个问题吗?

def entities_to_csv(entity_type,blob_file_name='',cursor='',batch_size=1000):
  more = True
  next_curs = None
  q = entity_type.query()
  results,next_curs,more = q.fetch_page(batch_size,start_cursor=Cursor.from_websafe_string(cursor))
  if results:
    try:
      if not blob_file_name:
        blob_file_name = files.blobstore.create(mime_type='text/csv',_blob_uploaded_filename='%s.csv' % entity_type.__name__)

      rows = [e.to_dict() for e in results]
      with files.open(blob_file_name, 'a') as f:
        writer = csv.DictWriter(f,restval='',extrasaction='ignore',fieldnames=results[0].keys())
        writer.writerows(rows)

      if more:
        deferred.defer(entity_type,blob_file_name,next_curs.to_websafe_string())
      else:
        files.finalize(blob_file_name)
    except DeadlineExceededError:
      deferred.defer(entity_type,blob_file_name,cursor)

稍后在代码中,类似于:

deferred.defer(entities_to_csv,Song)

2 个答案:

答案 0 :(得分:1)

当前解决方案的问题在于,每次写入预制件到blobstore时,内存都会增加。 blobstore是不可变的,并从内存中一次写入所有数据。

您需要在可以保存内存中所有记录的后端运行作业,您需要在应用程序中定义后端并使用_target='<backend name>'调用延迟。

答案 1 :(得分:0)

查看此Google I / O视频,从视频中大约23:15左右开始,使用MapReduce描述了您想要做的事情。你想要的代码是27:19

https://developers.google.com/events/io/sessions/gooio2012/307/