cam*_*ack 6 django amazon-s3 python-3.x boto3
我正在尝试将Django模型中的内容作为csv文件上传。我不想将文件保存在本地,而是将其保留在缓冲区中并上传到s3。当前,此代码不会按原样错误,并且会正确上传文件,但是文件为空。
file_name='some_file.csv'
fields = [list_of_fields]
header = [header_fields]
buff = io.StringIO()
writer = csv.writer(buff, dialect='excel', delimiter=',')
writer.writerow(header)
for value in some_queryset:
row = []
for field in fields:
# filling in the row
writer.writerow(row)
# Upload to s3
client = boto3.client('s3')
bucket = 'some_bucket_name'
date_time = datetime.datetime.now()
date = date_time.date()
time = date_time.time()
dt = '{year}_{month}_{day}__{hour}_{minute}_{second}'.format(
day=date.day,
hour=time.hour,
minute=time.minute,
month=date.month,
second=time.second,
year=date.year,
)
key = 'some_name_{0}.csv'.format(dt)
client.upload_fileobj(buff, bucket, key)
Run Code Online (Sandbox Code Playgroud)
如果我使用缓冲区的内容,那肯定是在写它:
content = buff.getvalue()
content.encode('utf-8')
print("content: {0}".format(content)) # prints the csv content
Run Code Online (Sandbox Code Playgroud)
编辑:我正在使用在缓冲区中创建的zip文件做类似的事情:
with zipfile.ZipFile(buff, 'w') as archive:
Run Code Online (Sandbox Code Playgroud)
写入存档(添加我正在生成的pdf文件),完成后,我执行此操作:buff.seek(0)这似乎是必要的。如果我在上面做类似的事情,它将出错:Unicode-objects must be encoded before hashing
Tho*_*ite 11
好吧,无视我先前的答案,我发现了实际的问题。
根据该upload_fileobj函数的boto3文档,第一个参数(Fileobj)需要实现一个read()方法,该方法返回字节:
Fileobj(类似文件的对象)-要上传的类似文件的对象。至少,它必须实现read方法,并且必须返回字节。
在read()一个对函数_io.StringIO对象返回一个字符串,而不是字节。我建议将StringIO对象替换为BytesIO对象,并添加必要的编码和解码。
这是一个最小的工作示例。这不是最有效的解决方案-基本思想是将内容复制到第二个BytesIO对象。
import io
import boto3
import csv
buff = io.StringIO()
writer = csv.writer(buff, dialect='excel', delimiter=',')
writer.writerow(["a", "b", "c"])
buff2 = io.BytesIO(buff.getvalue().encode())
bucket = 'changeme'
key = 'blah.csv'
client = boto3.client('s3')
client.upload_fileobj(buff2, bucket, key)
Run Code Online (Sandbox Code Playgroud)
小智 5
正如这里所解释的,使用方法 put_object 而不是 upload_fileobj 只会使用 io.STRINGIO 对象缓冲区完成这项工作。
所以在这里,为了匹配最初的示例:
client = boto3.client('s3')
client.upload_fileobj(buff2, bucket, key)
Run Code Online (Sandbox Code Playgroud)
会成为
client = boto3.client('s3')
client.put_object(Body=buff2, Bucket=bucket, Key=key, ContentType='application/vnd.ms-excel')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2614 次 |
| 最近记录: |