13

這應該是一個相當普遍的需求,也是一個簡單的過程:將數據批量上傳到appengine數據存儲區。如何將數據批量上傳到appengine數據存儲?舊方法不起作用

但是,在stackoverflow上提到的舊解決方案(下面的鏈接*)似乎沒有工作了。使用DB API上傳到數據存儲區時最合理的解決方案是散裝裝載程序方法,它不適用於NDB API

現在散裝裝載程序方法似乎已被棄用,舊鏈接仍存在在文檔中,導致錯誤的頁面。這裏有一個例子

https://developers.google.com/appengine/docs/python/tools/uploadingdata

這上面的鏈接仍然存在此頁上:https://developers.google.com/appengine/docs/python/tools/uploadinganapp

什麼是現在bulkloading數據推薦的方法?

這兩個可行的選擇似乎是1)使用remote_api或2)將CSV文件寫入GCS存儲桶並從中讀取數據。任何人都有成功使用這兩種方法的經驗?

任何指針將不勝感激。謝謝!

[*在下面的鏈接提供的解決方案不再有效]

[1] how does one upload data in bulk to a google appengine datastore?

[2] How to insert bulk data in Google App Engine Datastore?

回答

9

方法1:使用remote_api的

如何:寫一個bulkloader.yaml文件,直接使用「appcfg.py upload_data」從終端 命令,我不建議運行這種方法有以下幾個原因:1.巨大的延遲2.不支持NDB

方法2:GCS和使用mapreduce

上傳數據文件GCS:

使用「storage-file-transfer-json-python」的GitHub項目(chunked_transfer.py)從您的本地系統文件上傳到GCS。 確保從應用引擎管理控制檯生成適當的「client-secrets.json」文件。

的MapReduce:

使用 「appengine-mapreduce」 github上的項目。將「mapreduce」文件夾複製到您的項目頂層文件夾中。

下面的行添加到您的app.yaml文件:

includes: 
    - mapreduce/include.yaml 

下面是你的main.py文件

import cgi 
import webapp2 
import logging 
import os, csv 
from models import DataStoreModel 
import StringIO 
from google.appengine.api import app_identity 
from mapreduce import base_handler 
from mapreduce import mapreduce_pipeline 
from mapreduce import operation as op 
from mapreduce.input_readers import InputReader 

def testmapperFunc(newRequest): 
    f = StringIO.StringIO(newRequest) 
    reader = csv.reader(f, delimiter=',') 
    for row in reader: 
     newEntry = DataStoreModel(attr1=row[0], link=row[1]) 
     yield op.db.Put(newEntry) 

class TestGCSReaderPipeline(base_handler.PipelineBase): 
    def run(self, filename): 
     yield mapreduce_pipeline.MapreducePipeline(
       "test_gcs", 
       "testgcs.testmapperFunc", 
       "mapreduce.input_readers.FileInputReader", 
       mapper_params={ 
        "files": [filename], 
        "format": 'lines' 
       }, 
       shards=1) 

class tempTestRequestGCSUpload(webapp2.RequestHandler): 
    def get(self): 
     bucket_name = os.environ.get('BUCKET_NAME', 
            app_identity.get_default_gcs_bucket_name()) 

     bucket = '/gs/' + bucket_name 
     filename = bucket + '/' + 'tempfile.csv' 

     pipeline = TestGCSReaderPipeline(filename) 
     pipeline.with_params(target="mapreducetestmodtest") 
     pipeline.start() 
     self.response.out.write('done') 

application = webapp2.WSGIApplication([ 
    ('/gcsupload', tempTestRequestGCSUpload), 
], debug=True) 

要記住:

  1. MapReduce的項目用途現已被棄用的「Google Cloud Storage Files API」。所以未來的支持是不能保證的。
  2. 映射reduce爲數據存儲讀取和寫入增加了一個小開銷。

方法3:GCS和GCS客戶端庫

  1. 載CSV /文本文件以使用上述文件傳輸方法GCS。
  2. 使用gcs客戶端庫(將'cloudstorage'文件夾複製到您的應用程序頂層文件夾中)。

將以下代碼添加到應用程序main.py文件中。

import cgi 
import webapp2 
import logging 
import jinja2 
import os, csv 
import cloudstorage as gcs 
from google.appengine.ext import ndb 
from google.appengine.api import app_identity 
from models import DataStoreModel 

class UploadGCSData(webapp2.RequestHandler): 
    def get(self): 
     bucket_name = os.environ.get('BUCKET_NAME', 
            app_identity.get_default_gcs_bucket_name()) 
     bucket = '/' + bucket_name 
     filename = bucket + '/tempfile.csv' 
     self.upload_file(filename) 

    def upload_file(self, filename): 
     gcs_file = gcs.open(filename) 
     datareader = csv.reader(gcs_file) 
     count = 0 
     entities = [] 
     for row in datareader: 
      count += 1 
       newProd = DataStoreModel(attr1=row[0], link=row[1]) 
       entities.append(newProd) 

      if count%50==0 and entities: 
       ndb.put_multi(entities) 
       entities=[] 

     if entities: 
      ndb.put_multi(entities) 

application = webapp2.WSGIApplication([ 
    ('/gcsupload', UploadGCSData), 
], debug=True) 
+1

方法3將超時處理大量數據,除非您拆分BIG CSV。 – 2015-03-12 18:54:45

+0

@ sh4dydud3_88是的。這就是爲什麼我更喜歡大量數據的mapreduce方法的原因。另外,將CSV分割成每個CSV 20k個實體的塊也可以很好地工作。 – Sriram 2015-03-17 08:55:47

+0

當'gsutil'使得它像終端中的'cp'命令一樣簡單時,使用python腳本將文件上傳到GCS似乎有點愚蠢。 – the0ther 2017-02-23 15:04:07

3

遠程API方法,這表現在鏈接[1 ],仍然正常工作 - 儘管如果您的行數超過了幾百行,它會非常緩慢。

我已經成功地將GCS與MapReduce框架結合使用來下載而不是上載數據存儲的內容,但原理應該是相同的。請參閱mapreduce documentation:實際上,您只需要映射器步驟,因此您可以定義一個簡單函數,它接受CSV中的一行,並根據該數據創建數據存儲實體。

+0

謝謝Daniel。我們現在正在研究這種方法;將在此發佈更新。 – Cygorger 2014-08-30 05:44:16

+1

@Cygorger,你有沒有得到任何地圖下的mapreduce路徑?我是GAE的新手,我想從現有系統導入一些數據到數據存儲,以便我可以開始使用它,但我不知道從哪裏開始上傳數據。 – opensourcegeek 2015-01-03 10:05:44

+0

@opensourcegeek由sriram公佈的方法工作。希望有所幫助! – Cygorger 2015-01-12 04:47:13

1

截至2017年,最好的方法是使用名爲「Dataflow」(又名Apache Beam)的東西。 Java SDK非常易於使用,並且通過這些示例,您應該能夠在一天或半天內拼湊出一個可行的解決方案。

相關問題