2016-09-16 127 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