python 使用时间戳筛选器列出S3存储桶中的对象

yftpprvb  于 2023-02-18  发布在  Python
关注(0)|答案(3)|浏览(150)
    • 背景**

有没有办法得到一个s3 bucket上所有比特定时间戳更新的文件的列表,例如我试图找出并得到昨天下午修改的所有文件的列表。
特别是,我有一个名为foo-bar的存储桶,在这个存储桶中,我有一个名为prod的文件夹,我试图通过它解析文件。
"我一直在努力"
我参考了boto3 documentation,并得出了以下结论。

from boto3 import client
conn = client('s3')
conn.list_objects(Bucket='foo-bar', Prefix='prod/')['Contents']
    • 问题**

这个解决方案有两个问题,第一个是它只列出1000个文件,即使我有超过10,000个文件,另一个是我不知道我如何过滤时间?

pkmbmrz7

pkmbmrz71#

您可以根据时间戳进行过滤,执行以下操作:

import boto3
from datetime import datetime, timedelta
from dateutil.tz import tzutc

condition_timestamp = datetime.now(tz=tzutc()) - timedelta(days=2, hours=12)  #dynamic condition
#condition_timestamp = datetime(2023, 2, 17, tzinfo=tzutc()) #Fixed condition

s3 = boto3.client('s3')

paginator = s3.get_paginator('list_objects_v2')
 
s3_filtered_list = [obj for page in paginator.paginate(Bucket="foo-bar",Prefix="prod/") for obj in page["Contents"] if obj['LastModified'] > condition_timestamp]

s3_filtered_list

请注意,我给予了两个选项来创建基于时间戳的条件......动态(从现在起的x时间)或固定(x日期时间)

0tdrvxhp

0tdrvxhp2#

您可以尝试使用S3.Paginator.ListObjects,它将返回'LastModified': datetime(2015, 1, 1)作为Contents数组中对象元数据的一部分。然后,您可以根据LastModified条件将对象Key保存到本地列表中。

uubf1zoe

uubf1zoe3#

由于AWS S3 API不支持任何过滤概念,因此您需要根据返回的对象进行过滤。
此外,list_objectslist_objects_v2 API一次只支持返回1000个对象,因此您需要对结果进行分页,反复调用它以获取桶中的所有对象,有一个helper方法get_paginator可以为您处理此问题。
因此,您可以将这两个对象放在一起,得到一个存储桶中所有对象的列表,然后根据您认为合适的任何标准对它们进行过滤:

import boto3
from datetime import datetime, UTC

# Pick a target timestamp to filter objects on or after
# Note, it must be in UTC
target_timestamp = datetime(2023, 2, 1, tzinfo=UTC)
found_objects = []

# Create and use a paginator to list more than 1000 objects in the bucket
s3 = boto3.client('s3')
paginator = s3.get_paginator('list_objects_v2')
for page in paginator.paginate(Bucket=BUCKET):
    # Pull out each list of objects from each page
    for cur in page.get('Contents', []):
        # Check each object to see if it matches the target criteria
        if cur['LastModified'] >= target_timestamp:
            # If so, add it to the final list
            found_objects.append(cur)

# Just show the number of found objects in this example
print(f"Found {len(found_objects)} objects")

相关问题