AWS S3列表键包含字符串

时间:2017-12-19 01:43:11

标签: python amazon-web-services amazon-s3 aws-lambda

我在AWS Lambda函数中使用python列出包含特定id的s3存储桶中的密钥

for object in mybucket.objects.all():
            file_name = os.path.basename(object.key)
            match_id = file_name.split('_', 1)[0]

问题是如果s3存储桶有几千个文件,迭代效率非常低,有时lambda函数超时

这是一个示例文件名

https://s3.console.aws.amazon.com/s3/object/bucket-name/012345_abc_happy.jpg

我想只迭代键名中包含“012345”的对象 关于如何实现这一目标的任何好建议

2 个答案:

答案 0 :(得分:1)

以下是解决问题的方法。

S3将所有内容存储为对象,没有文件夹或文件名。这一切都是为了方便用户。

  

aws s3 ls s3:// bucket / folder1 / folder2 / filenamepart --recursive

将获取与该名称匹配的所有s3对象名称。

import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('bucketname')
for obj in my_bucket.objects.filter(Prefix='012345'):
    print(obj)

要加快列表速度,您可以并行运行多个脚本。

希望它有所帮助。

答案 1 :(得分:0)

通过删除os并使用字符串方法,您可以将速度提高30-40% 根据您对文件路径字符串的假设,您可以获得额外的加速:

使用os.path.basename()

%%timeit
match = "012345"
fname = "https://s3.console.aws.amazon.com/s3/object/bucket-name/012345_abc_happy.jpg"
os.path.basename(fname).split("_")[0] == match

# 1.03 µs ± 29.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

如果没有os,请先/然后再_分割:

%%timeit
match = "012345"
fname = "https://s3.console.aws.amazon.com/s3/object/bucket-name/012345_abc_happy.jpg"
fname.split("/")[-1].split("_")[0] == match

# 657 ns ± 11.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

如果您知道实际文件名中只有下划线,则只能使用一个split()

%%timeit
match = "012345"
fname = "https://s3.console.aws.amazon.com/s3/object/bucket-name/012345_abc_happy.jpg"
fname.split("_")[0][-6:] == match

# 388 ns ± 5.65 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)