All Products
Search
Document Center

Object Storage Service:Prevent overwrites of same-name objects

Last Updated:Oct 17, 2023

By default, if you upload an object that has the same name as an existing object, the existing object is overwritten by the uploaded object. This topic describes how to configure the x-oss-forbid-overwrite request header to prevent objects from being overwritten by objects with the same names when you copy objects or perform simple upload or multipart upload in Object Storage Service (OSS).

Usage notes

  • In this topic, the public endpoint of the China (Hangzhou) region is used. If you want to access OSS by using other Alibaba Cloud services in the same region as OSS, use an internal endpoint. For more information about the regions and endpoints supported by OSS, see Regions and endpoints.

  • In this topic, access credentials are obtained from environment variables. For more information about how to configure access credentials, see Configure access credentials.

  • In this topic, an OSSClient instance is created by using an OSS endpoint. If you want to create an OSSClient instance by using custom domain names or Security Token Service (STS), see Initialization.

Prevent overwrites in a simple upload task

The following sample code provides an example on how to prevent objects from being overwritten by objects that have the same names in simple upload:

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
# Specify the name of the bucket. 
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName')

# Upload the object. 
# Specify whether the object that is uploaded by calling the PutObject operation overwrites the existing object that has the same name. 
# By default, if x-oss-forbid-overwrite is not specified, the object that is uploaded overwrites the existing object that has the same name. 
# If x-oss-forbid-overwrite is set to false, the object that is uploaded overwrites the existing object that has the same name. 
# If x-oss-forbid-overwrite is set to true, the object that is uploaded cannot overwrite the existing object that has the same name. If an object that has the same name exists in the bucket, OSS returns an error. 
headers = {'x-oss-forbid-overwrite':'true'}
result = bucket.put_object('yourObjectName', 'content of object', headers=headers)

# Display the returned HTTP status code. 
print('http status: {0}'.format(result.status))
# Display the request ID. A request ID uniquely identifies a request. We recommend that you add this parameter to the logs. 
print('request_id: {0}'.format(result.request_id))
# Display the ETag value returned by the put_object method. 
print('ETag: {0}'.format(result.etag))
# Display the HTTP response headers. 
print('date: {0}'.format(result.headers['date']))

Prevent overwrites in an object copy task

  • Copy a small object

    The following sample code provides an example on how to copy a small object without overwriting the existing object that has the same name:

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    # Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
    # Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    # Specify the name of the bucket. 
    bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName')
    
    # Specify whether the object that is copied by calling the copy_object operation overwrites the existing object that has the same name. 
    # By default, if x-oss-forbid-overwrite is not specified, an existing object is overwritten by a copied object with the same name. 
    # If x-oss-forbid-overwrite is set to false, an existing object is overwritten by a copied object with the same name. 
    # If x-oss-forbid-overwrite is set to true, an existing object is not overwritten by a copied object with the same name. If the existing object has the same name as the copied object, an error is reported. 
    headers = dict()
    headers = {'x-oss-forbid-overwrite':'true'}
    bucket.copy_object('yourSourceBucketName', 'yourSourceObjectName', 'yourDestinationObjectName', headers=headers)
  • Copy a large object

    The following sample code provides an example on how to prevent an existing object from being overwritten by a large object with the same name when you copy the large object by using multipart copy:

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    from oss2.models import PartInfo
    from oss2 import determine_part_size
    # Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
    # Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
    # Specify the name of the bucket. 
    bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName')
    
    src_object = 'yourSourceObjectName'
    dst_object = 'yourDestinationObjectName'
    
    total_size = bucket.head_object(src_object).content_length
    part_size = determine_part_size(total_size, preferred_size=100 * 1024)
    
    # Initiate a multipart upload task. 
    # Specify whether to overwrite an object that has the same name when you copy an object. 
    # By default, if x-oss-forbid-overwrite is not specified, the object that is copied overwrites the existing object that has the same name. 
    # If x-oss-forbid-overwrite is set to false, the object that is copied overwrites the existing object that has the same name. 
    # If x-oss-forbid-overwrite is set to true, an existing object is not overwritten by a copied object with the same name. If the existing object has the same name as the copied object, an error is reported. 
    headers = dict()
    headers = {'x-oss-forbid-overwrite':'true'}
    upload_id = bucket.init_multipart_upload(dst_object, headers=headers).upload_id
    parts = []
    
    # Copy each part. 
    part_number = 1
    offset = 0
    while offset < total_size:
        num_to_upload = min(part_size, total_size - offset)
        byte_range = (offset, offset + num_to_upload - 1)
    
        result = bucket.upload_part_copy(bucket.bucket_name, src_object, byte_range,dst_object, upload_id, part_number)
        parts.append(PartInfo(part_number, result.etag))
    
        offset += num_to_upload
        part_number += 1
    
    # Complete the multipart copy task. 
    # Specify whether to overwrite an object that has the same name when you copy an object. 
    # By default, if x-oss-forbid-overwrite is not specified, the object that is uploaded overwrites the existing object that has the same name. 
    # If x-oss-forbid-overwrite is set to false, the object that is uploaded overwrites the existing object that has the same name. 
    # If x-oss-forbid-overwrite is set to true, an existing object is not overwritten by a copied object with the same name. If the existing object has the same name as the copied object, an error is reported. 
    headers = dict()
    headers = {'x-oss-forbid-overwrite':'true'}
    bucket.complete_multipart_upload(dst_object, upload_id, parts, headers=headers)

Prevent overwrites in a multipart upload task

The following sample code provides an example on how to prevent objects from being overwritten when you use multipart upload to upload objects with the same names:

# -*- coding: utf-8 -*-
import os
from oss2 import SizedFileAdapter, determine_part_size
from oss2.models import PartInfo
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
# Specify the name of the bucket. 
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName')

key = 'yourObjectName'
filename = 'yourLocalFile'

total_size = os.path.getsize(filename)
# Specify the determine_part_size method to determine the part size. 
part_size = determine_part_size(total_size, preferred_size=100 * 1024)

# Initiate a multipart upload task. 
# Specify whether to overwrite the existing object that has the same name when you perform multipart upload. 
# By default, if x-oss-forbid-overwrite is not specified, the object that is uploaded overwrites the existing object that has the same name. 
# If x-oss-forbid-overwrite is set to false, the object that is uploaded overwrites the existing object that has the same name. 
# If x-oss-forbid-overwrite is set to true, the object that is uploaded cannot overwrite the existing object that has the same name. If an object that has the same name exists in the bucket, OSS returns an error. 
headers = {'x-oss-forbid-overwrite':'true'}
upload_id = bucket.init_multipart_upload(key, headers=headers).upload_id
parts = []

# Upload the parts. 
with open(filename, 'rb') as fileobj:
    part_number = 1
    offset = 0
    while offset < total_size:
        num_to_upload = min(part_size, total_size - offset)
        # The SizedFileAdapter(fileobj, size) method generates a new object and recalculates the position from which the append operation starts. 
        result = bucket.upload_part(key, upload_id, part_number,
                                    SizedFileAdapter(fileobj, num_to_upload))
        parts.append(PartInfo(part_number, result.etag))

        offset += num_to_upload
        part_number += 1

# Complete the multipart upload task. 
# Specify whether to overwrite the existing object that has the same name when you perform multipart upload. 
# By default, if x-oss-forbid-overwrite is not specified, the object that is uploaded overwrites the existing object that has the same name. 
# If x-oss-forbid-overwrite is set to false, the object that is uploaded overwrites the existing object that has the same name. 
# If x-oss-forbid-overwrite is set to true, the object that is uploaded cannot overwrite the existing object that has the same name. If an object that has the same name exists in the bucket, OSS returns an error. 
headers = {'x-oss-forbid-overwrite':'true'}
bucket.complete_multipart_upload(key, upload_id, parts, headers=headers)

# Verify the result of the multipart upload task. 
with open(filename, 'rb') as fileobj:
    assert bucket.get_object(key).read() == fileobj.read()

References

  • For more information about the API operation that you can call to perform simple upload, see PutObject.

  • For more information about the API operation that you can call to copy an object, see CopyObject.

  • For more information about the API operations that you can call to perform multipart upload, see InitiateMultipartUpload and CompleteMultipartUpload.