写一个CSV以存储在Google云端存储中

时间:2016-09-16 05:56:08

标签: python csv google-app-engine google-cloud-storage

背景:我正在Python / AppEngine项目中获取数据并创建.tsv文件,以便我可以使用d3.js创建图表。现在我正在写每个页面加载的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 云储存。迭代并将TSV / CSV文件写入云存储应该很简单,对吧?
  2. 我以完全错误的方式解决了这个问题 完全,甚至应该使用BlobStore或db.TextProperty() 存储此.tsv数据。 (文件不是那么大;绝对是 远低于1MB)
  3. 我很感激任何帮助!

    编辑 - 完整追溯

    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'>.
    

2 个答案:

答案 0 :(得分:4)

您仍在尝试根据回复创建作者:

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上传处理程序中移动此代码。

答案 1 :(得分:0)

问题是writer.writerow没有返回任何内容。返回类型为None,您尝试将其写入gcs_file