【问题标题】:Download S3 Objects by List of Keys Using Boto3使用 Boto3 按密钥列表下载 S3 对象
【发布时间】:2023-03-11 05:49:01
【问题描述】:

我有一个从缓存中检索的键列表,我想从 S3 下载关联的对象(文件),而不必为每个键发出请求。

假设我有以下键数组:

key_array = [
    '20160901_0750_7c05da39_INCIDENT_MANIFEST.json',
    '20161207_230312_ZX1G222ZS3_INCIDENT_MANIFEST.json',
    '20161211_131407_ZX1G222ZS3_INCIDENT_MANIFEST.json',
    '20161211_145342_ZX1G222ZS3_INCIDENT_MANIFEST.json',
    '20161211_170600_FA68T0303607_INCIDENT_MANIFEST.json'
]

我正在尝试在另一个 SO 问题上做类似于 this answer 的事情,但修改如下:

import boto3

s3 = boto3.resource('s3')

incidents = s3.Bucket(my_incident_bucket).objects(key_array)

for incident in incidents:
    # Do fun stuff with the incident body
    incident_body = incident['Body'].read().decode('utf-8')

我的最终目标是避免为列表中的每个键单独访问 AWS API。我还想避免不得不将整个桶拉下来并过滤/迭代完整的结果。

【问题讨论】:

  • avoid hitting the AWS API separately for every keyavoid having to pull the whole bucket down and filtering/iterating the full results。你还能怎么做?你的钥匙有规律吗?
  • @helloV 我希望 S3 可以接受我在请求中发送的键数组(或以其他方式分隔的列表),并返回匹配的对象。我一直在翻阅 boto3 和 AWS 的文档,但没有找到任何东西,所以我想在这里问一下。这些键有一个共同的前缀,但我的缓存中的响应可能会因搜索参数而异。
  • 除非你所有的键都有相同的前缀,否则没有这样的功能。
  • 因此,如果我有 10K 个文件并且它们都有一个公共前缀,我可以抓取所有匹配该公共前缀的文件。但是,如果我只想要 10K 文件中的 10 个文件怎么办?如果我已经知道键名,那么为了使用 10 个文件而必须获取所有 10K 文件似乎很昂贵。
  • 一次请求无法获取多个对象的内容。

标签: python amazon-web-services amazon-s3 boto3


【解决方案1】:

我认为您将获得的最好的结果是 n API 调用,其中 n 是您的 key_array 中的键数。 s3 的亚马逊 API 没有提供太多基于键的服务器端过滤方式,除了前缀。以下是在 n API 调用中获取它的代码:

import boto3
s3 = boto3.client('s3')

for key in key_array:
    incident_body = s3.get_object(Bucket="my_incident_bucket", Key=key)['Body']

    # Do fun stuff with the incident body

【讨论】:

  • 考虑到我的事件列表可以任意多,我决定将这部分工作移至后台进程并缓存实际的 json 结果。支持 PostgreSQL 原生 JSON 数据类型。
  • 是否有一些新的 API 可以实现现在摆脱多个 API 调用的目标?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多