从 boto3 检索 S3 存储桶中的子文件夹名称

新手上路,请多包涵

使用 boto3,我可以访问我的 AWS S3 存储桶:

 s3 = boto3.resource('s3')
bucket = s3.Bucket('my-bucket-name')

现在,存储桶包含文件夹 first-level ,它本身包含几个以时间戳命名的子文件夹,例如 1456753904534 。我需要知道这些子文件夹的名称以用于我正在做的另一项工作,我想知道是否可以让 boto3 为我检索这些子文件夹。

所以我尝试了:

 objs = bucket.meta.client.list_objects(Bucket='my-bucket-name')

它给出了一个字典,它的键’Contents’给了我所有的三级文件而不是二级时间戳目录,实际上我得到了一个包含以下内容的列表

{u’ETag’: ‘“etag”’, u’Key’: 一级/1456753904534/part-00014’, u’LastModified’: datetime.datetime(2016, 2, 29, 13, 52, 24, tzinfo =tzutc()),

u’Owner’: {u’DisplayName’: ‘owner’, u’ID’: ‘id’},

u’Size’: 大小,u’StorageClass’: ‘storageclass’}

您可以看到特定文件,在本例中为 part-00014 被检索,而我想单独获取目录的名称。原则上,我可以从所有路径中删除目录名称,但是在第三级检索所有内容以获得第二级是丑陋和昂贵的!

我也试过 这里 报道的东西:

 for o in bucket.objects.filter(Delimiter='/'):
    print(o.key)

但我没有获得所需级别的文件夹。

有没有办法解决这个问题?

原文由 mar tin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

S3 是一个对象存储,它没有真正的目录结构。 “/”相当美观。人们想要一个目录结构的一个原因是,他们可以维护/修剪/添加一棵树到应用程序。对于 S3,您将此类结构视为某种索引或搜索标签。

要在 S3 中操作对象,您需要 boto3.client 或 boto3.resource,例如列出所有对象

import boto3
s3 = boto3.client("s3")
all_objects = s3.list_objects(Bucket = 'bucket-name')

http://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.list_objects

事实上,如果 s3 对象名称是使用 ‘/’ 分隔符存储的。更新版本的 list_objects (list_objects_v2) 允许您将响应限制为以指定前缀开头的键。

要将项目限制为某些子文件夹下的项目:

     import boto3
    s3 = boto3.client("s3")
    response = s3.list_objects_v2(
            Bucket=BUCKET,
            Prefix ='DIR1/DIR2',
            MaxKeys=100 )

文档

另一种选择是使用 python os.path 函数来提取文件夹前缀。问题是这将需要列出不需要的目录中的对象。

 import os
s3_key = 'first-level/1456753904534/part-00014'
filename = os.path.basename(s3_key)
foldername = os.path.dirname(s3_key)

# if you are not using conventional delimiter like '#'
s3_key = 'first-level#1456753904534#part-00014'
filename = s3_key.split("#")[-1]

关于 boto3 的提醒:boto3.resource 是一个不错的高级 API。使用 boto3.client 与 boto3.resource 各有利弊。如果您开发内部共享库,使用 boto3.resource 将为您提供一个覆盖所用资源的黑盒层。

原文由 mootmoot 发布,翻译遵循 CC BY-SA 4.0 许可协议

下面的一段代码仅返回 s3 存储桶中“文件夹”中的“子文件夹”。

 import boto3
bucket = 'my-bucket'
#Make sure you provide / in the end
prefix = 'prefix-name-with-slash/'

client = boto3.client('s3')
result = client.list_objects(Bucket=bucket, Prefix=prefix, Delimiter='/')
for o in result.get('CommonPrefixes'):
    print 'sub folder : ', o.get('Prefix')

更详细的可以参考 https://github.com/boto/boto3/issues/134

原文由 Dipankar 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题