¿Cómo eliminar archivos del bucket de amazon s3?


91

Necesito escribir código en Python que borrará el archivo requerido de un bucket de Amazon s3. Puedo conectarme al bucket de Amazon s3 y también guardar archivos, pero ¿cómo puedo eliminar un archivo?


¿Qué biblioteca de Python (si corresponde) está utilizando para la compatibilidad con S3? ¿O va directamente a las interfaces REST o SOAP en su código Python?
TJ Crowder

1
Estoy usando la biblioteca de Python boto.s3
Suhail

Respuestas:


94

Usando boto3(actualmente versión 1.4.4) use S3.Object.delete().

import boto3

s3 = boto3.resource('s3')
s3.Object('your-bucket', 'your-key').delete()

1
Si el objeto no está presente, ¿arrojará un error?
Akash Tantri

2
@AkashTantri No lo he probado personalmente, pero el documento dice que elimina la versión nula (si hay una) [...] Si no hay una versión nula, Amazon S3 no elimina ningún objeto. Entonces, supongo que no arrojará un error. Si lo intentas (haz algo como s3.Object('existing-bucket', 'bogus-key').delete()y verás qué pasa. s3.Object('bogus-bucket', 'bogus-key').delete()
Prueba

Funciona como un encanto, ese es el verdadero poder de Python
yunus

@yunus ¿es este un comentario serio?
Henry Henrinson

¿ your-keySignifica aquí el nombre de archivo real your-bucketen S3?
Underoos

91

encontré una forma más de hacerlo usando el boto:

from boto.s3.connection import S3Connection, Bucket, Key

conn = S3Connection(AWS_ACCESS_KEY, AWS_SECERET_KEY)

b = Bucket(conn, S3_BUCKET_NAME)

k = Key(b)

k.key = 'images/my-images/'+filename

b.delete_key(k)

10
Si desea eliminar TODO en un cubo, puede hacer:for x in b.list(): b.delete_key(x.key)
jontsai

19
Me encanta cómo aparece en mi archivobucket.list()
Artur Sapek

Para que este fragmento de código funcione como se presenta, necesitará importar Buckety Keytambién. Como en:from boto.s3.connection import S3Connection, Bucket, Key
Nick Chammas

Por >>> from boto.s3.connection import S3Connection, Bucket, Key Traceback (most recent call last): File "<console>", line 1, in <module> ImportError: No module named boto.s3.connectionfavor, actualice la respuesta a boto3
Harry Moreno

1
Lo descubrí y redacté
Harry Moreno

74

Con el SDK de Python boto3 (y asumiendo que las credenciales están configuradas para AWS), lo siguiente eliminará un objeto específico en un depósito:

import boto3

client = boto3.client('s3')
client.delete_object(Bucket='mybucketname', Key='myfile.whatever')

6
@Rob La documentación de boto3 es engañosa. creará un marcador de eliminación si el objeto está versionado. De lo contrario, eliminará el objeto.
jarmod

1
Limpio y sencillo. Podría ser la respuesta aceptada y definitivamente debería combinarse con la respuesta de @ Kohányi Róbert, ya que ambos son los mejores enfoques para la tarea.
PaulB

15

Bienvenido a 2020, aquí está la respuesta en Python / Django:

from django.conf import settings 
import boto3   
s3 = boto3.client('s3')
s3.delete_object(Bucket=settings.AWS_STORAGE_BUCKET_NAME, Key=f"media/{item.file.name}")

Me tomó demasiado tiempo encontrar la respuesta y fue tan simple como esto.


4

Me sorprende que no haya una manera tan fácil key.delete()::

from boto.s3.connection import S3Connection, Bucket, Key

conn = S3Connection(AWS_ACCESS_KEY, AWS_SECERET_KEY)
bucket = Bucket(conn, S3_BUCKET_NAME)
k = Key(bucket = bucket, name=path_to_file)
k.delete()

4

Intente buscar un método actualizado , ya que Boto3 puede cambiar de vez en cuando. Solía my_bucket.delete_objects () :

import boto3
from boto3.session import Session

session = Session(aws_access_key_id='your_key_id',
                  aws_secret_access_key='your_secret_key')

# s3_client = session.client('s3')
s3_resource = session.resource('s3')
my_bucket = s3_resource.Bucket("your_bucket_name")

response = my_bucket.delete_objects(
    Delete={
        'Objects': [
            {
                'Key': "your_file_name_key"   # the_name of_your_file
            }
        ]
    }
)


3

¿A través de qué interfaz? Usando la interfaz REST, simplemente envía una eliminación :

DELETE /ObjectName HTTP/1.1
Host: BucketName.s3.amazonaws.com
Date: date
Content-Length: length
Authorization: signatureValue

A través de la interfaz SOAP :

<DeleteObject xmlns="http://doc.s3.amazonaws.com/2006-03-01">
  <Bucket>quotes</Bucket>
  <Key>Nelson</Key>
  <AWSAccessKeyId> 1D9FVRAYCP1VJEXAMPLE=</AWSAccessKeyId>
  <Timestamp>2006-03-01T12:00:00.183Z</Timestamp>
  <Signature>Iuyz3d3P0aTou39dzbqaEXAMPLE=</Signature>
</DeleteObject>

Si está utilizando una biblioteca de Python como boto , debería exponer una función de "eliminar", como delete_key().


sí, estoy usando esa biblioteca de Python, pero ¿eliminará eso el archivo? ¿Debo hacerlo de esta manera: k.key = 'images / anon-images / small /' + nombre de archivo k.delete_key () es correcto? Por favor hagamelo saber.
Suhail

@Suhail: No he usado esa biblioteca, pero desde la fuente que vinculé, lo que realmente está haciendo es una DELETEllamada a través de la interfaz REST. Así que sí, a pesar del nombre "delete_key" (que estoy de acuerdo que no está claro), realmente está eliminando el objeto al que hace referencia la clave.
TJ Crowder

1
¿Qué pasa con la eliminación de muchos archivos con un prefijo común en el nombre? ¿S3 permite una eliminación masiva para tal caso, o eliminarlos uno por uno (que es lento) es obligatorio?
Illarion Kovalchuk

@Shaman: No soy un experto en S3, pero hasta donde yo , solo puedes eliminar un archivo específico. Pero probablemente quieras hacer eso como una pregunta para llamar la atención de los expertos de S3.
TJ Crowder

Justo después de comentar aquí, agregué esa pregunta. Todavía tiene 2 vistas :)
Illarion Kovalchuk

2

La forma más sencilla de hacer esto es:

import boto3
s3 = boto3.resource("s3")
bucket_source = {
            'Bucket': "my-bcuket",
            'Key': "file_path_in_bucket"
        }
s3.meta.client.delete(bucket_source)

1

Por ahora, resolví el problema utilizando la utilidad de Linux s3cmd . Lo usé así en Python:

delFile = 's3cmd -c /home/project/.s3cfg del s3://images/anon-images/small/' + filename
os.system(delFile)

1
No es exactamente pitónico invocar una subcapa para comunicarse con S3 (una biblioteca o una transacción HTTP directa sería más elegante), pero aún funciona. No creo que merezca un voto negativo. +1.
Randall Cook

1

Me ha funcionado, pruébalo.

import boto
import sys
from boto.s3.key import Key
import boto.s3.connection

AWS_ACCESS_KEY_ID = '<access_key>'
AWS_SECRET_ACCESS_KEY = '<secret_access_key>'
Bucketname = 'bucket_name' 

conn = boto.s3.connect_to_region('us-east-2',
        aws_access_key_id=AWS_ACCESS_KEY_ID,
        aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
        is_secure=True,              
        calling_format = boto.s3.connection.OrdinaryCallingFormat(),
        )
bucket = conn.get_bucket(Bucketname)

k = Key(bucket)

k.key = 'filename to delete'
bucket.delete_key(k)   

1

puede hacerlo usando aws cli: https://aws.amazon.com/cli/ y algún comando de Unix.

estos comandos aws cli deberían funcionar:

aws s3 rm s3://<your_bucket_name> --exclude "*" --include "<your_regex>" 

si desea incluir subcarpetas, debe agregar la bandera --recursiva

o con comandos de Unix:

aws s3 ls s3://<your_bucket_name>/ | awk '{print $4}' | xargs -I%  <your_os_shell>   -c 'aws s3 rm s3:// <your_bucket_name>  /% $1'

explicación:

  1. enumerar todos los archivos en el cubo --pipe ->
  2. obtener el cuarto parámetro (es el nombre del archivo) --pipe -> // puede reemplazarlo con el comando de Linux para que coincida con su patrón
  3. ejecutar borrar script con aws cli

1

si está tratando de eliminar el archivo usando su propia consola de host local, entonces puede intentar ejecutar este script de Python asumiendo que ya ha asignado su identificación de acceso y clave secreta en el sistema

import boto3

#my custom sesssion
aws_m=boto3.session.Session(profile_name="your-profile-name-on-local-host")
client=aws_m.client('s3')

#list bucket objects before deleting 
response = client.list_objects(
    Bucket='your-bucket-name'
)
for x in response.get("Contents", None):
    print(x.get("Key",None));

#delete bucket objects
response = client.delete_object(
    Bucket='your-bucket-name',
    Key='mydocs.txt'
)

#list bucket objects after deleting
response = client.list_objects(
    Bucket='your-bucket-name'
)
for x in response.get("Contents", None):
    print(x.get("Key",None));

0

Lo siguiente funcionó para mí (basado en el ejemplo de un modelo de Django, pero puedes usar el código del deletemétodo por sí solo).

import boto3
from boto3.session import Session
from django.conf import settings

class Video(models.Model):
    title=models.CharField(max_length=500)
    description=models.TextField(default="")
    creation_date=models.DateTimeField(default=timezone.now)
    videofile=models.FileField(upload_to='videos/', null=True, verbose_name="")
    tags = TaggableManager()

    actions = ['delete']

    def __str__(self):
        return self.title + ": " + str(self.videofile)

    def delete(self, *args, **kwargs):
        session = Session (settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
        s3_resource = session.resource('s3')
        s3_bucket = s3_resource.Bucket(settings.AWS_STORAGE_BUCKET_NAME)

        file_path = "media/" + str(self.videofile)
        response = s3_bucket.delete_objects(
            Delete={
                'Objects': [
                    {
                        'Key': file_path
                    }
                ]
            })
        super(Video, self).delete(*args, **kwargs)

0

A continuación, se muestra un fragmento de código que puede usar para eliminar el depósito,

import boto3, botocore
from botocore.exceptions import ClientError

s3 = boto3.resource("s3",aws_access_key_id='Your-Access-Key',aws_secret_access_key='Your-Secret-Key')
s3.Object('Bucket-Name', 'file-name as key').delete()

0

por favor intente este código

import boto3   
s3 = boto3.client('s3')
s3.delete_object(Bucket="s3bucketname", Key="s3filepath")
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.