如何在S3中使用boto3进行版本控制?

Old*_*ity 4 python amazon-s3 boto3

我正在使用带有boto3的版本化S3存储桶.如何检索给定密钥的所有版本(甚至所有密钥的所有版本)?我可以做这个:

for os in b.objects.filter(Prefix=pref):
    print("os.key")
Run Code Online (Sandbox Code Playgroud)

但这只给我每个键的最新版本.

非常感谢,

al7*_*l76 10

import boto3

bucket = 'bucket name'
key = 'key'
s3 = boto3.resource('s3')
versions = s3.Bucket(bucket).object_versions.filter(Prefix=key)

for version in versions:
    obj = version.get()
    print(obj.get('VersionId'), obj.get('ContentLength'), obj.get('LastModified'))
Run Code Online (Sandbox Code Playgroud)

我不能相信,因为我有同样的问题,但我在这里找到


cho*_*rbs 8

boto3 s3 客户端有一个list_object_versions方法。

resp = client.list_object_versions(Prefix=prefix, Bucket=bucket)

for obj in [*resp['Versions'], *resp.get('DeleteMarkers', [])]:
    print(f"Key: {obj['Key']}")
    print(f"VersionId: {obj['VersionId']}")
    print(f"LastModified: {obj['LastModified']}")
    print(f"IsLatest: {obj['IsLatest']}")
    print(f"Size: {obj.get('Size', 0)/1e6}")
Run Code Online (Sandbox Code Playgroud)

假设您想要删除除当前版本之外的所有版本,您可以通过将不存在的对象添加IsLatestto_delete列表中,然后运行以下命令来实现此目的:

for obj in to_delete:
    print(client.delete_object(Bucket=bucket, Key=obj['Key'], VersionId=obj['VersionId']))
Run Code Online (Sandbox Code Playgroud)


Luc*_*rts 6

现有的答案描述了如何获取对象的版本 ID 。我们对使用对象的版本感兴趣,这通常涉及访问部分或全部对象。

首先获取版本 ID。我将使用al76此处的答案来获取版本 ID来说明boto3.resourceboto3.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'))
Run Code Online (Sandbox Code Playgroud)

接下来我们需要获取实际的版本化对象,有几种方法可以做到这一点,具体取决于您是否有 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)
Run Code Online (Sandbox Code Playgroud)

请注意,如果您的对象是 csv 文件(等),则每个event都是一个botocore.response.StreamingBody对象,并且可能不对应于一行。

现在,作为替代方法,您可能拥有 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)
Run Code Online (Sandbox Code Playgroud)

第三种选择与第一种非常相似,直接使用资源、存储桶和对象。

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)
Run Code Online (Sandbox Code Playgroud)

第四个选项(也使用 s3客户端)是直接下载文件。

object_original_version = s3.meta.client.download_file(bucket, key, '/tmp/' + key, ExtraArgs={'VersionId': s3_object_versions[0]})
Run Code Online (Sandbox Code Playgroud)

/tmp然后您可以通过open()调用或更专门针对文件格式的方式读取文件。

在您的代码中,您可能希望用try/except等包装它们来处理错误,除非这是原型设计/实验工作。