我在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”的对象 关于如何实现这一目标的任何好建议
答案 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)