[英]Boto3 S3, sort bucket by last modified
我需要使用 Boto3 从 S3 获取项目列表,但我希望它通过相反的顺序返回默认排序顺序(降序),而不是返回它。
我知道你可以通过 awscli 做到这一点:
aws s3api list-objects --bucket mybucketfoo --query "reverse(sort_by(Contents,&LastModified))"
并且可以通过 UI 控制台实现(不确定这是在客户端还是服务器端完成)
我似乎看不到如何在 Boto3 中执行此操作。
我目前正在获取所有文件,然后进行排序……但这似乎有些过分,尤其是当我只关心 10 个左右的最新文件时。
过滤系统似乎只接受 s3 的前缀,没有别的。
如果bucket中的对象不多,可以使用Python根据自己的需要进行排序。
定义一个 lambda 来获取最后修改时间:
get_last_modified = lambda obj: int(obj['LastModified'].strftime('%s'))
获取所有对象并按上次修改时间对它们进行排序。
s3 = boto3.client('s3')
objs = s3.list_objects_v2(Bucket='my_bucket')['Contents']
[obj['Key'] for obj in sorted(objs, key=get_last_modified)]
如果要反转排序:
[obj['Key'] for obj in sorted(objs, key=get_last_modified, reverse=True)]
我对@helloV 在下面发布的内容做了一些小改动。 它不是 100% 最佳的,但它完成了工作,但目前 boto3 有限制。
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('myBucket')
unsorted = []
for file in my_bucket.objects.filter():
unsorted.append(file)
files = [obj.key for obj in sorted(unsorted, key=get_last_modified,
reverse=True)][0:9]
似乎无法通过使用 boto3 进行排序。 根据文档,boto3 只支持集合的这些方法:
all(), filter(**kwargs), page_size(**kwargs), limit(**kwargs)
希望这在某种程度上有所帮助。 https://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.ServiceResource.buckets
以上略有改进:
import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('myBucket')
files = my_bucket.objects.filter()
files = [obj.key for obj in sorted(files, key=lambda x: x.last_modified,
reverse=True)]
要获取 S3 中文件夹中最后修改的文件:
import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('bucket_name')
files = my_bucket.objects.filter(Prefix='folder_name/subfolder_name/')
files = [obj.key for obj in sorted(files, key=lambda x: x.last_modified,
reverse=True)][0:2]
print(files)
获取最后修改的两个文件:
files = [obj.key for obj in sorted(files, key=lambda x: x.last_modified,
reverse=True)][0:2]
一种更简单的方法,使用 python3 sorted() 函数:
import boto3
s3 = boto3.resource('s3')
myBucket = s3.Bucket('name')
def obj_last_modified(myobj):
return myobj.last_modified
sortedObjects = sorted(myBucket.objects.all(), key=obj_last_modified, reverse=True)
您现在有一个反向排序列表,按每个Object的 'last_modified' 属性排序。
keys = []
kwargs = {'Bucket': 'my_bucket'}
while True:
resp = s3.list_objects_v2(**kwargs)
for obj in resp['Contents']:
keys.append(obj['Key'])
try:
kwargs['ContinuationToken'] = resp['NextContinuationToken']
except KeyError:
break
这将使您按排序顺序获得所有键
s3 = boto3.client('s3')
get_last_modified = lambda obj: int(obj['LastModified'].strftime('%Y%m%d%H%M%S'))
def sortFindLatest(bucket_name):
resp = s3.list_objects(Bucket=bucket_name)
if 'Contents' in resp:
objs = resp['Contents']
files = sorted(objs, key=get_last_modified)
for key in files:
file = key['Key']
cx = s3.get_object(Bucket=bucket_name, Key=file)
这对我来说可以按日期和时间排序。 我正在使用 Python3 AWS lambda。 您的里程可能会有所不同。 它可以优化,我特意让它离散。 正如之前的帖子中提到的,可以添加“reverse=True”来更改排序顺序。
所以我的回答可用于上次修改,但我认为如果您来到此页面,您可能希望能够以其他方式对文件进行排序。 所以用一块石头杀死 2 只鸟:
在此线程中,您可以找到内置方法sorted
。 如果您阅读文档或这篇文章,您会发现您可以创建自己的 function 来优先考虑对象的排序方式。 因此,例如在我的情况下。 我有一堆文件,前面有一些数字,可能还有一封信。 它看起来像这样:
1.svg
10.svg
100a.svg
11.svg
110.svg
...
2.svg
20b.svg
200.svg
...
10011b.svg
...
etc
我希望它按前面的数字排序——我不关心数字后面的字母,所以我写了这个 function:
def my_sort(x):
try:
# this will take the file name, split over the file type and take just the name, cast it to an int, and return it
return int(x.split(".")[0])
# if it couldn't do that
except ValueError:
# it will take the file name, split it over the extension, and take the name
n = x.split(".")[0]
s = ""
# then for each character
for e in n:
# check to see if it is a digit and append it to a string if it is
if e.isdigit():
s += e
# if its not a digit, it hit the character at the end of the name, so return it
else:
return int(s)
这意味着现在我可以这样做:
import boto3
s3r = boto3.resource('s3')
bucket = s3r.Bucket('my_bucket')
os = bucket.objects.filter(Prefix="my_prefix/")
os = [o.key.split("/")[-1] for o in os]
os = sorted(os, key=my_sort)
# do whatever with the sorted data
这将按名称中的数字后缀对我的文件进行排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.