2016-09-16 130 views
0

背景:我在我的Python/AppEngine項目中獲取數據並創建.tsv文件,以便我可以使用d3.js創建圖表。現在我正在寫每個頁面加載的CSV;我想將文件一次存儲在Google雲端存儲中,然後從中讀取。編寫CSV以存儲在Google雲端存儲中

如何我目前正在寫的文件,每次頁面加載!:

def get(self): ## this gets called when loading myfile.tsv from d3.js 
    datalist = MyEntity.all() 
    self.response.headers['Content-Type'] = 'text/csv' 
    writer = csv.writer(self.response.out, delimiter='\t') 
    writer.writerow(['field1', 'field2']) 
    for eachco in datalist: 
     writer.writerow([eachco.variable1, eachco.variable2]) 

雖然效率不高,這是工作就好了。

使用this Google Cloud Storage documentation,我一直試圖得到這樣的工作:

def get(self): 
    filename = '/bucket/myfile.tsv' 
    datalist = MyEntity.all() 
    bucket_name = os.environ.get('BUCKET_NAME', app_identity.get_default_gcs_bucket_name()) 
    write_retry_params = gcs.RetryParams(backoff_factor=1.1) 
    writer = csv.writer(self.response.out, delimiter='\t') 
    gcs_file = gcs.open(filename, 'w', content_type='text/csv', retry_params=write_retry_params) 
    gcs_file.write(writer.writerow(['field1', 'field2'])) 
    for eachco in datalist: 
     gcs_file.write(writer.writerow([eachco.variable1, eachco.variable2])) 
    gcs_file.close() 

但我發現了:

TypeError: Expected str but got <type 'NoneType'>. 

我認爲csv.writer的輸出會一個字符串,所以我不知道爲什麼我得到TypeError。

所以我能想到的兩種情況:

  1. 我有東西在我的代碼到硅通孔寫入 雲存儲搞砸了。通過遍歷並將TSV/CSV文件寫入雲存儲應該很簡單,對吧?
  2. 我已經完全錯過了這個完全錯誤的方式 ,甚至應該使用BlobStore或db.TextProperty() 來存儲此.tsv數據。 (文件不是那麼大;絕對是 遠低於1MB)

我會很感激任何幫助!

編輯 - 全回溯

Traceback (most recent call last): 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1530, in __call__ 
    rv = self.router.dispatch(request, response) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1278, in default_dispatcher 
    return route.handler_adapter(request, response) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1102, in __call__ 
    return handler.dispatch() 
    File "/mydirectory/myapp/handlers.py", line 21, in dispatch 
    webapp2.RequestHandler.dispatch(self) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 572, in dispatch 
    return self.handle_exception(e, self.app.debug) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 570, in dispatch 
    return method(*args, **kwargs) 
    File "/mydirectory/myapp/thisapp.py", line 384, in get 
    gcs_file.write(writer.writerow(['field1', 'field2'])) 
    File "lib/cloudstorage/storage_api.py", line 754, in write 
    raise TypeError('Expected str but got %s.' % type(data)) 
TypeError: Expected str but got <type 'NoneType'>. 
+0

您忘記設置響應標題。 –

+0

你可以添加完整的追溯? –

+0

我不知道你想用這個'gcs_file.write(str(writer.writerow([eachco.variable1,eachco.variable2])))''來實現。 –

回答

3

你還在嘗試對響應創建作者:

writer = csv.writer(self.response.out, delimiter='\t') 

你需要寫GCS文件。事情是這樣的:

datalist = MyEntity.all() 
    bucket_name = os.environ.get('BUCKET_NAME', app_identity.get_default_gcs_bucket_name()) 
    filename = os.path.join(bucket_name, 'myfile.tsv') 
    write_retry_params = gcs.RetryParams(backoff_factor=1.1) 
    gcs_file = gcs.open(filename, 'w', content_type='text/csv', retry_params=write_retry_params) 
    writer = csv.writer(gcs_file, delimiter='\t') 
    writer.writerow(['field1', 'field2']) 
    for eachco in datalist: 
     writer.writerow([eachco.variable1, eachco.variable2]) 
    gcs_file.close() 

注:

  • 沒有實際測試過
  • 我還調整了文件名使用bucket_name
  • 如果你這樣做的get()請求可能要檢查該文件已經存在,如果有的話,使用它,否則你會在每次請求時生成它。或者,您可以在任務或.tsv上傳處理程序中移動此代碼。
+0

工作正常!我仍然必須使用filename ='/bucket/myfile.tsv'行,因爲這是GCS明確要求的格式。 (錯誤是ValueError:路徑應該有格式/桶/文件名,但得到了app_default_bucket/myfile.tsv) –

+0

啊,缺少領先的'/'我懷疑。嘗試使用'filename ='/%s/myfile.tsv'%bucket_name'(假設默認應用程序存儲區的名稱在生產環境中爲'bucket'可能不是個好主意)。 –

0

的問題是,writer.writerow不返回任何東西。返回類型將爲None,並且您正試圖將其寫入gcs_file