现有答案描述了如何获取对象的版本 ID。我们有兴趣使用对象的版本,这通常涉及访问部分或全部对象。
首先获取版本 ID。我将在这里使用al76 的答案获取版本ID 来说明boto3.resource 和boto3.client 的示例。
import boto3
from collections import deque
bucket = 'bucket name'
key = 'key'
s3 = boto3.resource('s3')
versions = s3.Bucket(bucket).object_versions.filter(Prefix=key)
s3_object_versions = deque()
for version in versions:
obj = version.get()
s3_object_versions.appendleft(obj.get('VersionId'))
接下来我们需要获取实际的版本化对象,有几种方法可以做到这一点,具体取决于您是否拥有 s3 资源或 s3 客户端。鉴于我们获得了资源的版本 ID,我们将从那里开始。
# using the first version of the object
obj_version = s3.ObjectVersion(bucket, key, s3_object_versions[0]).get()
# if this object is really large this loop might execute for awhile
for event in obj_version['Body']:
print(event)
请注意,每个 event 都是一个 botocore.response.StreamingBody 对象,如果您的对象是 csv 文件(等),则可能不对应一行。
现在作为一种替代方法,您可能有一个 s3 客户端,而不是一个 s3 资源对象。在 s3 资源中,您可以通过.meta 访问客户端。这是代码:
response = s3.meta.client.get_object(Bucket=bucket, Key=key, VersionId=s3_object_versions[-1])
# same caveat as above, for loop may run for awhile if object is large
for event in response['Body']:
print(event)
第三个选项与第一个非常相似,直接使用资源、存储桶和对象。
object = s3.Bucket(bucket).Object(key).get()
object_version = object.Version(s3_object_versions[0]).get()
# again careful if object is large-will run awhile and fill stdout
for event in object_version['Body']:
print(event)
第四个选项——同样使用 s3 客户端是直接下载文件。
object_original_version = s3.meta.client.download_file(bucket, key, '/tmp/' + key, ExtraArgs={'VersionId': s3_object_versions[0]})
然后您可以通过open() 调用或更专业的文件格式从/tmp 读取文件。
在您的代码中,您可能希望用try/except 等包装这些以处理错误,除非这是原型设计/实验工作。