为何S3 Resource对象filter会返回不含文件的前缀对象?
问题
使用boto3的S3 resource时,对bucket执行objects.filter(Prefix='prefix/a/'),结果里包含key为prefix/a/的ObjectSummary;但执行objects.filter(Prefix='prefix/b/')时却没有这类对象,这是为什么?
代码示例:
s3 = boto3.resource('s3') bucket = s3.Bucket('bucket_name') for obj in bucket.objects.filter(Prefix='prefix/a/'): print(obj) # 输出结果: # s3.ObjectSummary(bucket_name='bucket_name', key='prefix/a/') # s3.ObjectSummary(bucket_name='bucket_name', key='prefix/a/file1.csv') # s3.ObjectSummary(bucket_name='bucket_name', key='prefix/a/file2.csv') # s3.ObjectSummary(bucket_name='bucket_name', key='prefix/a/file3.csv') for obj in bucket.objects.filter(Prefix='prefix/b/'): print(obj) # 输出结果: # s3.ObjectSummary(bucket_name='bucket_name', key='prefix/b/file4.csv') # s3.ObjectSummary(bucket_name='bucket_name', key='prefix/b/file5.csv') # s3.ObjectSummary(bucket_name='bucket_name', key='prefix/b/file6.csv')
原因分析
核心原因很简单:你的S3桶里确实存在key为prefix/a/的对象,但prefix/b/对应的这个对象不存在。
S3本质是对象存储,没有真正的"文件夹"概念——所谓的文件夹,其实是人为创建的、key以斜杠结尾的空对象(通常文件大小为0)。当你调用objects.filter(Prefix='xxx/')时:
- 如果桶里存在
xxx/这个key的对象,它会被包含在过滤结果里 - 如果不存在这个对象,过滤结果只会返回所有以
xxx/为前缀的实际文件对象
你看到prefix/a/出现在结果里,说明之前有人通过S3控制台、SDK或其他工具创建了这个空对象;而prefix/b/没有对应的空对象,所以结果里只有它下面的文件。
如果要验证这一点,可以用以下代码检查两个key是否存在:
from botocore.exceptions import ClientError # 检查prefix/a/是否存在 try: s3.Object('bucket_name', 'prefix/a/').load() print("prefix/a/ 对象存在") except ClientError as e: if e.response['Error']['Code'] == "404": print("prefix/a/ 对象不存在") # 检查prefix/b/是否存在 try: s3.Object('bucket_name', 'prefix/b/').load() print("prefix/b/ 对象存在") except ClientError as e: if e.response['Error']['Code'] == "404": print("prefix/b/ 对象不存在")
内容的提问来源于stack exchange,提问作者imatiasmb
相关产品推荐
相关产品推荐

