De forma predeterminada, si carga un objeto que tiene el mismo nombre que uno ya existente, el objeto existente se sobrescribe. En este tema se describe cómo configurar el encabezado de solicitud x-oss-forbid-overwrite para evitar que los objetos existentes se sobrescriban al copiar objetos o al ejecutar una carga simple o una carga por partes (multipart upload).
Notas
En este tema se utiliza el endpoint público de la región China (Hangzhou). Si necesita acceder a OSS desde otros servicios de Alibaba Cloud ubicados en la misma región que OSS, utilice un endpoint interno. Para obtener más información sobre las regiones y los endpoints de OSS, consulte Regions and endpoints.
Las credenciales de acceso se obtienen a partir de variables de entorno. Para conocer el procedimiento de configuración de estas credenciales, consulte Configure access credentials using OSS SDK for Python 1.0.
Este tema muestra cómo crear una instancia de OSSClient con un endpoint de OSS. Para configuraciones alternativas, como usar un dominio personalizado o autenticarse con credenciales de Security Token Service (STS), consulte Initialization.
Evitar sobrescrituras en una tarea de carga simple
A continuación se muestra un ejemplo de código para evitar que los objetos existentes se sobrescriban durante una carga simple cuando coinciden los nombres:
# -*- 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.ProviderAuthV4(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.
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"
# Specify the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# 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']))
Evitar sobrescrituras en una tarea de copia de objetos
-
Copiar un objeto pequeño
El siguiente ejemplo de código muestra cómo copiar un objeto pequeño sin sobrescribir un objeto existente que tenga el mismo nombre:
# -*- 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 your 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) -
Copiar un objeto grande
Este fragmento de código ilustra cómo evitar que un objeto grande sobrescriba a otro existente con el mismo nombre durante una copia por partes (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.ProviderAuthV4(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. endpoint = "https://oss-cn-hangzhou.aliyuncs.com" # Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4. region = "cn-hangzhou" # Specify the name of your bucket. bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region) 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)
Evitar sobrescrituras en una tarea de carga por partes
El siguiente ejemplo de código muestra cómo impedir que un objeto existente se sobrescriba al utilizar la carga por partes para cargar un objeto con el mismo nombre:
# -*- 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.ProviderAuthV4(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.
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"
# Specify the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
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()
Referencias
Para obtener más información sobre la operación de API que permite ejecutar una carga simple, consulte PutObject.
Si desea conocer los detalles de la operación de API utilizada para copiar un objeto, consulte CopyObject.
Para consultar las operaciones de API correspondientes a la carga por partes, revise InitiateMultipartUpload y CompleteMultipartUpload.