boto3-在S3中获取仅在过去一个月上传的文件



我正在编写一个python3 lambda函数,该函数需要返回自该函数运行以来过去30天内上传到S3存储桶的所有文件。

我应该如何处理?理想情况下,我只想迭代过去30天的文件,而不想迭代其他文件——我正在迭代的S3存储桶中有成千上万的文件,也许每个月最多会更新/上传100个。像这样迭代每个文件并比较日期是非常低效的。AWS API网关也有29秒的时间限制。

如有任何帮助,我们将不胜感激。谢谢

您需要遍历对象列表(示例代码:列出大小为csv格式的s3 bucket(,并比较Python代码中的日期(示例代码从s3 bucket中获取一天的文件路径(。

列出对象时没有过滤器(除了前缀(。

另一种选择是使用Amazon S3 Inventory,它可以提供一个列出bucket内容的每日CSV文件。您可以解析该CSV,而不是列出对象。

一个更极端的选择是保留一个单独的对象数据库,每当添加/删除对象时都需要更新该数据库。这可以通过触发AWS Lambda函数的Amazon S3事件来完成。不过还有很多工作要做。

我不能给你100%的答案,因为你已经要求上传日期,但如果你能接受"上次修改"的值,这个代码片段应该可以完成任务:

import boto3
import datetime
paginator = boto3.resource('s3').meta.client.get_paginator('list_objects')
date = datetime.datetime.now() - datetime.timedelta(30)
filtered_files = (page['Key'] for page in paginator.paginate(Bucket="bucketname").search(f"Contents[?to_string(LastModified)>='"{date}"']"))

对于过滤,我使用了JMESPath

从架构师的角度

瓶颈在于是否可以在30秒内迭代所有对象。如果本机文件太多,您可以使用更多选项:

  1. 创建一个由S3:PutObject事件触发的aws lambda函数,并将S3密钥和last_modified_at信息存储到Dynamodb(aws键值NoSQL数据库(中。然后,您可以很容易地使用Dynamodb来过滤S3密钥,并相应地检索那些S3对象
  2. C创建一个由S3:PutObject事件触发的aws lambda函数,并将文件移动到分区的S3密钥模式位置,如s3://bucket/datalake/year=${year}/month=${month}/day=${day}/your-file.csv。然后,您可以轻松地使用分区信息来定位对象的子集,这符合30秒的硬性限制

从编程的角度

下面的代码片段使用这个库s3pathlib:解决了您的问题

from datetime import datetime, timedelta
from s3pathlib import S3path
# define a folder
p_dir = S3Path("bucket/my-folder/")
# find one month ago datetime
now = datetime.utcnow()
one_month_ago = now - timedelta(days=30)
# filter by last modified
for p in p_bucket.iter_objects().filter(
# any Filterable Attribute can be used for filtering
S3Path.last_modified_at >= one_month_ago 
):
# do whatever you like
print(p.console_url) # click link to open it in console, inspect 

如果你想使用其他S3Path属性进行过滤,并使用其他比较器,甚至定义你的自定义过滤器,你可以遵循以下文档

相关内容

最新更新