本文介绍如何在受版本控制的存储空间(Bucket)中删除单个或多个文件(Object))以及指定前缀的(Prefix)的文件。

版本控制下的删除行为

版本控制下的删除行为说明如下:

  • 未指定versionId(临时删除):

    如果在未指定versionId的情况下执行删除操作时,默认不会删除Object的当前版本,而是对当前版本插入删除标记(Delete Marker)。当执行GetObject操作时,OSS会检测到当前版本为删除标记,并返回404 Not Found。此外,响应中会返回header:x-oss-delete-marker = true以及新生成的删除标记的版本号x-oss-version-id

    x-oss-delete-marker的值为true,表示与返回的x-oss-version-id对应的版本为删除标记。

  • 指定versionId(永久删除):

    如果在指定versionId的情况下执行删除操作时,OSS会根据params中指定的versionId参数永久删除该版本。如果要删除ID为“null”的版本,请在params参数中添加params['versionId'] = “null”,OSS将“null”字符串当成“null”的versionId,从而删除versionId为“null”的Object。

删除单个文件

以下提供了永久删除及临时删除单个Object的示例。

  • 永久删除
    以下代码用于指定versionId对Object进行永久删除:
    # -*- coding: utf-8 -*-
    import os
    import oss2
    
    # 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    # Endpoint以杭州为例,其它Region请按实际情况填写。
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    # 填写不包含Bucket名称在内的Object的完整路径,例如example/test.txt。
    object_name = '<yourObjectName>'
    
    # 指定Object的versionId,也可以是删除标记的versionId。
    params = dict()
    params['versionId'] = '<yourObjectVersionIdOrDeleteMarkerVersionId>'
    
    # 删除指定versionId的Object或指定versionId的删除标记关联的Object。
    result = bucket.delete_object(object_name, params=params)
    print("delete object name: ", object_name)
    # 如果指定的是Object的versionId,则返回的delete_marker为None且返回的versionId为指定Object的versionId。
    # 如果指定的是删除标记的versionId,则返回的delete_marker为True且返回的versionId为指定删除标记的versionId。
    if result.delete_marker:
        print("delete del-marker versionid: ",result.versionid)
    else:
        print("delete object versionid:", result.versionid)
  • 临时删除
    以下代码用于不指定versionId对Object进行临时删除:
    # -*- coding: utf-8 -*-
    import os
    import oss2
    
    # 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    # Endpoint以杭州为例,其它Region请按实际情况填写。
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    object_name = '<yourObjectName>'
    
    # 不指定versionId对Object进行临时删除,此操作会为Object添加删除标记。
    result = bucket.delete_object(object_name)
    # 查看删除标记。
    print("delete marker: ", result.delete_marker)
    # 查看返回删除标记的versionId。
    print("delete marker versionid: ", result.versionid)

删除单个文件的详细信息请参见DeleteObject

删除多个文件

以下提供了永久删除以及临时删除多个Object的示例。

  • 永久删除
    以下代码用于指定versionId对多个Object及删除标记进行永久删除:
    # -*- coding: utf-8 -*-
    import os
    import oss2
    from oss2.models import BatchDeleteObjectVersion
    from oss2.models import BatchDeleteObjectVersionList
    
    # 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    # Endpoint以杭州为例,其它Region请按实际情况填写。
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    
    version_list = BatchDeleteObjectVersionList()
    # 可以传入Object或者删除标记的versionId。
    obj1_versionid = '<yourObject1VersionId>'
    obj1_del_marker_versionid = '<yourObject1DelMarkerVersionId>'
    obj2_versionid = '<yourObject2VersionId>'
    obj2_del_marker_versionid = '<yourObject2DelMarkerVersionId>'
    version_list.append(BatchDeleteObjectVersion(key='<yourObject1Name>', versionid=obj1_versionid))
    version_list.append(BatchDeleteObjectVersion(key='<yourObject1Name>', versionid=obj1_del_marker_versionid))
    version_list.append(BatchDeleteObjectVersion(key='<yourObject2Name>', versionid=obj2_versionid))
    version_list.append(BatchDeleteObjectVersion(key='<yourObject2Name>', versionid=obj2_del_marker_versionid))
    
    # 批量删除指定versionId的Object或删除标记。
    result = bucket.delete_object_versions(version_list)
    # 查看被删除Object或删除标记的versionId。
    for del_version in result.delete_versions:
        print('del object name:', del_version.key)
        # 查看删除的是否是删除标记。
        print('Is del marker:', del_version.delete_marker)
        # 如果是删除标记,则打印删除的删除标记的versionId,否则打印删除Object的versionId。
        if del_version.delete_marker :
            print('del object del_marker.versionid', del_version.delete_marker_versionid)
        else:
            print('del object versionid:', del_version.versionid)
  • 临时删除
    以下代码用于不指定versionId对多个Object进行临时删除:
    # -*- coding: utf-8 -*-
    import os
    import oss2
    from oss2.models import BatchDeleteObjectVersion
    from oss2.models import BatchDeleteObjectVersionList
    
    # 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    # Endpoint以杭州为例,其它Region请按实际情况填写。
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    
    
    key_list = ['<yourObject1Name>', '<yourObject2Name>']
    # 执行不指定versionId的删除操作后,将为Object添加删除标记。
    result = bucket.batch_delete_objects(key_list)
    for del_version in result.delete_versions:
        print('key name:', del_version.key)
        # 打印返回的删除标记。
        print('Is del marker:', del_version.delete_marker)
        print('key del_marker.versionid', del_version.delete_marker_versionid)

删除多个文件的详细信息请参见DeleteMultipleObjects

删除指定前缀(prefix)的文件

以下代码用于删除指定前缀的文件:

# -*- coding: utf-8 -*-
import oss2

# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# Endpoint以杭州为例,其它Region请按实际情况填写。
bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
prefix = "<yourKeyPrefix>"

# 列举所有指定前缀文件的versionId并删除这些文件。
next_key_marker = None
next_versionid_marker = None
while True:
    result = bucket.list_object_versions(prefix=prefix, key_marker=next_key_marker, versionid_marker=next_versionid_marker)

    for version_info in result.versions:
        bucket.delete_object(version_info.key, params={'versionId': version_info.versionid})

    for del_marker_info in result.delete_marker:
        bucket.delete_object(del_marker_info.key, params={'versionId': del_marker_info.versionid})

    is_truncated = result.is_truncated

    if is_truncated:
        next_key_marker = result.next_key_marker
        next_versionid_marker = result.next_versionid_marker
    else:
        break