【发布时间】:2015-09-10 22:41:09
【问题描述】:
我需要创建一个 CSV 并将其上传到 S3 存储桶。由于我是动态创建文件的,所以如果我可以在创建文件时将其直接写入 S3 存储桶,而不是在本地写入整个文件,然后在最后上传文件,那会更好。
有没有办法做到这一点?我的项目是用 Python 编写的,而且我对这门语言还很陌生。到目前为止,这是我尝试过的:
import csv
import csv
import io
import boto
from boto.s3.key import Key
conn = boto.connect_s3()
bucket = conn.get_bucket('dev-vs')
k = Key(bucket)
k.key = 'foo/foobar'
fieldnames = ['first_name', 'last_name']
writer = csv.DictWriter(io.StringIO(), fieldnames=fieldnames)
k.set_contents_from_stream(writer.writeheader())
我收到了这个错误:BotoClientError: s3 does not support chunked transfer
更新:我找到了一种直接写入 S3 的方法,但我找不到清除缓冲区而不实际删除我已经写过的行的方法。所以,例如:
conn = boto.connect_s3()
bucket = conn.get_bucket('dev-vs')
k = Key(bucket)
k.key = 'foo/foobar'
testDict = [{
"fieldA": "8",
"fieldB": None,
"fieldC": "888888888888"},
{
"fieldA": "9",
"fieldB": None,
"fieldC": "99999999999"}]
f = io.StringIO()
fieldnames = ['fieldA', 'fieldB', 'fieldC']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
k.set_contents_from_string(f.getvalue())
for row in testDict:
writer.writerow(row)
k.set_contents_from_string(f.getvalue())
f.close()
向文件写入 3 行,但是我无法释放内存来写入大文件。如果我添加:
f.seek(0)
f.truncate(0)
到循环,然后只写入文件的最后一行。有什么方法可以释放资源而不删除文件中的行?
【问题讨论】:
-
即使您可以按照自己的意愿写入 S3,由于一致性挑战,我不推荐它。为什么你认为不写本地会更好?如果出现异常或问题,您是否需要部分 S3 对象?我想不会。
-
我希望直接写来提高效率。本质上,如果我在本地编写文件并上传它,我将添加上传作为附加步骤,并清理本地文件。我不介意有一个不完整的文件 - 如果我也在本地编写它,我可能会有一个不完整的文件。系统将是幂等的,要么删除一个处于错误状态的文件,要么继续它。
标签: python csv amazon-s3 boto buffering