写入 CSV 以存储在 Google 云存储中
Write a CSV to store in Google Cloud Storage
背景:我正在我的 Python/AppEngine 项目中获取数据并创建一个 .tsv 文件,以便我可以使用 d3.js 创建图表。现在我正在为每个页面加载编写 CSV;我想改为将文件存储在 Google Cloud Storage 中并从那里读取它。
每次加载页面时,我当前是如何写入文件的!:
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。
所以我可以想到两种情况:
- 我在将 tsv 写入到的代码中搞砸了
云储存。不过,遍历并将 TSV/CSV 文件写入 Cloud Storage 应该很简单,对吧?
- 我以完全错误的方式解决了这个问题
完全,甚至应该使用 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'>.
问题是 writer.writerow
没有 return 任何东西。 return 类型将是 None
,而您正试图将其写入 gcs_file
。
您仍在尝试根据以下回复创建作者:
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
上传处理程序中。
背景:我正在我的 Python/AppEngine 项目中获取数据并创建一个 .tsv 文件,以便我可以使用 d3.js 创建图表。现在我正在为每个页面加载编写 CSV;我想改为将文件存储在 Google Cloud Storage 中并从那里读取它。
每次加载页面时,我当前是如何写入文件的!:
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。
所以我可以想到两种情况:
- 我在将 tsv 写入到的代码中搞砸了 云储存。不过,遍历并将 TSV/CSV 文件写入 Cloud Storage 应该很简单,对吧?
- 我以完全错误的方式解决了这个问题 完全,甚至应该使用 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'>.
问题是 writer.writerow
没有 return 任何东西。 return 类型将是 None
,而您正试图将其写入 gcs_file
。
您仍在尝试根据以下回复创建作者:
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
上传处理程序中。