我正在从Google App Engine Datastore(使用Python(中提取大量数据,我需要将其写入GCS(Google Cloud Storage(上的csv文件。
我通过使用 iter 查询获取 ~10k 个实体并推迟任务来执行此任务。不幸的是,GCS不支持附加到文件,因此在每次运行任务时,我都被迫打开并读取整个文件,关闭它,然后将内容写入新文件并将新获取的一批数据添加到其中。
我正在使用 UnicodeWriter/UnicodeReader 来处理类似于以下内容的 csv 文件:https://docs.python.org/2/library/csv.html#examples
我的问题是,当文件变大时,它往往会占用大量实例内存,有时会超过限制。在这种情况下,有没有办法最大限度地减少大量内存使用?
在GCS上处理>32MB的大csv文件的任何示例都非常受欢迎。
Google Cloud Storage 可以愉快地接受基本上无限大小的对象,但您的问题略有不同,首先是构造对象。
您可以使用Google Cloud Storage的合成支持来提供帮助。但是,撰写是有限制的。您总共最多可以组合 1024 个对象(每次调用 32 个对象,但可以组合该对象的结果,也可以组合该对象的结果,依此类推,直到有 1024 个原始源对象组合在一起(。因此,只有当将总大小分成 1024 个部分使它们足够小以满足您的用例时,组合才会起作用。
但是,也许这已经足够好了。如果是这样,这里有一些资源:
撰写功能的文档:https://cloud.google.com/storage/docs/composite-objects#_Compose
我不确定您是否正在使用 App Engine 云存储库,但如果您使用的是,不幸的是它不支持撰写。你必须获取更通用的Google API Python客户端并调用objects#compose方法,记录在这里:https://cloud.google.com/storage/docs/json_api/v1/objects/compose
以下是使用它的相关示例:
composite_object_resource = {
'contentType': 'text/csv', # required
'contentLanguage': 'en',
}
compose_req_body = {
'sourceObjects': [
{'name': source_object_name_1},
{'name': source_object_name_2}],
'destination': composite_object_resource
}
req = client.objects().compose(
destinationBucket=bucket_name,
destinationObject=composite_object_name,
body=compose_req_body)
resp = req.execute()
当你写这样的东西时:
with gcs.open(gcs_filename, 'w', content_type=b'multipart/x-zip') as gf:
....
这里 gf 是一个cloudstorage.storage_api。StreamingBuffer,可以对其进行酸洗以在链式任务中追加数据。但我还没有尝试过这个。