首页 > 解决方案 > 使用 Boto3 下载 S3 文件

问题描述

我目前正在编写一个脚本,我需要将 S3 文件下载到创建的目录。我目前使用凭据创建一个 boto3 会话,从该会话创建一个 boto3 资源,然后使用它从我的 s3 位置查询和下载。它看起来像下面的示例:

s3_session = boto3.Session(...)
s3_resource = s3_session.resource('s3')

mnt_loc = '/home/username/tmp/'

s3_loc = urlparse('s3://bucket_name/path1/path2/', allow_fragments=False)
s3_files = []
bucket = s3_resource.Bucket(s3_loc.netloc)
for elem in bucket.objects:
    s3_files.append(elem)

for elem in s3_files:
    s3_resource.Bucket(elem.bucket_name).download_file(elem.key, mnt_loc + elem.key.rsplit('/', 1)[-1])

理论上,我认为这会将指定的文件从 s3 位置复制到我的挂载位置,同时保持文件的命名。执行时,我得到一个

[Errno 2] 没有这样的文件或目录:/home/username/tmp/filename.csv.F2H1nxR0。

为什么这个过程不起作用,为什么这个过程将这些随机字符串附加到我的文件名的末尾,如显示的“F2H1nxR0”?

标签: pythonamazon-s3boto3

解决方案


我想出了一种方法来纠正我收到的错误。问题是我将 s3.ObjectSummary 部分传递到我的 download_file() 中。为了修复这个错误,我将所有部分转换为字符串,如下所示:

s3_session = boto3.Session(...)
s3_resource = s3_session.resource('s3')

mnt_loc = '/home/username/tmp/'

s3_loc = urlparse('s3://bucket_name/path1/path2/', allow_fragments=False)
s3_files = []
bucket = s3_resource.Bucket(s3_loc.netloc)
for elem in bucket.objects:
    s3_files.append(elem)

for elem in s3_files:
    bucket = str(elem.bucket_name)
    path = str(elem.key)
    file_name = str(elem.key.rsplit('/', 1)[-1])
    s3_resource.Bucket(bucket).download_file(path, mnt_loc + file_name)

这消除了 [Errno 2] No such file or directory: /home/username/tmp/filename.csv.F2H1nxR0 并摆脱了附加到文件名末尾的 8 个字符串。感谢大家的帮助,因为它使我找到了此修复程序。


推荐阅读