Boto3 S3: TypeError: coercing to Unicode: need string or buffer, file found
Boto3 S3: TypeError: coercing to Unicode: need string or buffer, file found
正在尝试将文件上传到 S3:
# boto3 s3 client
s3.put_object(Bucket=self.bucket,
Body=open(upload_file, 'rb'),
Key=k.key,
SSECustomerAlgorithm='AES256',
SSECustomerKey=base64.b64encode(data_key),
SSECustomerKeyMD5=base64.b64encode(data_key_md5)
)
并在这一行出现错误:
TypeError: coercing to Unicode: need string or buffer, file found
我的 upload_file
变量是 <type 'file'>
和 dir
:
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']
切换到 open(upload_file, 'rb').read()
无济于事。此外,我的文件可能很大(1gb pr 左右),将它们保留为字符串是不合理的。
我知道如果我将 upload_file
设置为文件路径它会起作用,但我没有这个文件在磁盘上,它是通过表单提交的。
更新
这很奇怪,但是当我使用测试文件或字符串(为了测试)时遇到了类似的问题:
TypeError: expected string or buffer
这是对以下内容的回复:
# boto3 s3 client
s3.put_object(Bucket=self.bucket,
# put existing filr
Body=open('/tml/existing-file', 'rb'), # adding read() wont help
# ...
)
字符串相同:
# boto3 s3 client
s3.put_object(Bucket=self.bucket,
# put existing filr
Body='some random string',
# ...
)
我建议您将输入流写入临时文件并使用 Bucket.upload_file
传输文件。在 Web 服务应用程序中将大文件保存在内存中并不好。考虑到您有多个并发上传请求,这总共会消耗大量内存。
import tempfile
import shutil
file_ = file_like_object_from_form_submit
with tempfile.NamedTemporaryFile() as tmpfile:
shutil.copyfileobj(file_, tmpfile)
tmpfile.flush()
self.bucket.upload_file(tmpfile.name, path)
不知道为什么我不能让它与 boto3 一起工作,但这里的代码与以前的 boto2 版本一起工作。唯一的区别是:根据官方文档,您需要在 header 中添加 put 参数:
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
在我的代码示例中,它看起来像:
headers.update({
'x-amz-server-side-encryption-customer-algorithm': 'AES256',
'x-amz-server-side-encryption-customer-key': base64.b64encode(data_key),
'x-amz-server-side-encryption-customer-key-MD5': base64.b64encode(data_key_md5)
})
k.set_contents_from_file(upload_file, headers=headers)
如您所见,upload_file
在这种情况下工作正常。
正在尝试将文件上传到 S3:
# boto3 s3 client
s3.put_object(Bucket=self.bucket,
Body=open(upload_file, 'rb'),
Key=k.key,
SSECustomerAlgorithm='AES256',
SSECustomerKey=base64.b64encode(data_key),
SSECustomerKeyMD5=base64.b64encode(data_key_md5)
)
并在这一行出现错误:
TypeError: coercing to Unicode: need string or buffer, file found
我的 upload_file
变量是 <type 'file'>
和 dir
:
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']
切换到 open(upload_file, 'rb').read()
无济于事。此外,我的文件可能很大(1gb pr 左右),将它们保留为字符串是不合理的。
我知道如果我将 upload_file
设置为文件路径它会起作用,但我没有这个文件在磁盘上,它是通过表单提交的。
更新
这很奇怪,但是当我使用测试文件或字符串(为了测试)时遇到了类似的问题:
TypeError: expected string or buffer
这是对以下内容的回复:
# boto3 s3 client
s3.put_object(Bucket=self.bucket,
# put existing filr
Body=open('/tml/existing-file', 'rb'), # adding read() wont help
# ...
)
字符串相同:
# boto3 s3 client
s3.put_object(Bucket=self.bucket,
# put existing filr
Body='some random string',
# ...
)
我建议您将输入流写入临时文件并使用 Bucket.upload_file
传输文件。在 Web 服务应用程序中将大文件保存在内存中并不好。考虑到您有多个并发上传请求,这总共会消耗大量内存。
import tempfile
import shutil
file_ = file_like_object_from_form_submit
with tempfile.NamedTemporaryFile() as tmpfile:
shutil.copyfileobj(file_, tmpfile)
tmpfile.flush()
self.bucket.upload_file(tmpfile.name, path)
不知道为什么我不能让它与 boto3 一起工作,但这里的代码与以前的 boto2 版本一起工作。唯一的区别是:根据官方文档,您需要在 header 中添加 put 参数: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html 在我的代码示例中,它看起来像:
headers.update({
'x-amz-server-side-encryption-customer-algorithm': 'AES256',
'x-amz-server-side-encryption-customer-key': base64.b64encode(data_key),
'x-amz-server-side-encryption-customer-key-MD5': base64.b64encode(data_key_md5)
})
k.set_contents_from_file(upload_file, headers=headers)
如您所见,upload_file
在这种情况下工作正常。