jak usunąć pliki z wiadra amazon s3?


91

Muszę napisać kod w Pythonie, który usunie wymagany plik z zasobnika Amazon s3. Jestem w stanie połączyć się z zasobnikiem Amazon s3, a także zapisywać pliki, ale jak mogę usunąć plik?


Której (jeśli w ogóle) biblioteki Pythona używasz do obsługi S3? A może zamierzasz przejść bezpośrednio do interfejsów REST lub SOAP w kodzie Pythona?
TJ Crowder

1
Używam biblioteki Pythona boto.s3
Suhail

Odpowiedzi:


94

Korzystanie boto3(obecnie wersja 1.4.4) use S3.Object.delete().

import boto3

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

1
Jeśli obiekt nie jest obecny, czy zgłosi błąd?
Akash Tantri

2
@AkashTantri Osobiście nie próbowałem, ale dokument mówi, że usuwa wersję zerową (jeśli istnieje) [...] Jeśli nie ma wersji zerowej, Amazon S3 nie usuwa żadnych obiektów. Więc przypuszczam, że nie spowoduje to błędu. Jeśli zdarzy ci się spróbować (po prostu zrób coś takiego s3.Object('existing-bucket', 'bogus-key').delete()i zobacz, co się stanie. Spróbuj także s3.Object('bogus-bucket', 'bogus-key').delete().
Kohányi Róbert

Działa jak urok, to prawdziwa moc pytona
yunus

@yunus czy to poważny komentarz?
Henry Henrinson

Czy your-keytutaj oznacza rzeczywistą nazwę pliku w your-bucketS3?
Underoos

91

znalazłem jeszcze jeden sposób na zrobienie tego za pomocą 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
Jeśli chcesz usunąć WSZYSTKO w wiadrze, możesz zrobić:for x in b.list(): b.delete_key(x.key)
jontsai

19
Uwielbiam sposób w moim pliku okazuje się byćbucket.list()
Artur Sapek

Aby ten fragment kodu działał jak przedstawiono, musisz zaimportować, Bucketa Keytakże. Jak w:from boto.s3.connection import S3Connection, Bucket, Key
Nick Chammas

Otrzymuję, >>> 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.connectionproszę, zaktualizuj odpowiedź na boto3
Harry Moreno

1
wymyśliłem to i napisałem rozwiązanie harrymoreno.com/2017/04/24/ ...
Harry Moreno

74

Używając Python boto3 SDK (i zakładając, że poświadczenia są skonfigurowane dla AWS), poniższe czynności usuwają określony obiekt w zasobniku:

import boto3

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

6
@Rob Dokumentacja boto3 jest myląca. utworzy znacznik usuwania, jeśli obiekt jest wersjonowany. W przeciwnym razie usunie obiekt.
jarmod

1
Czyste i proste. Może to być akceptowana odpowiedź i zdecydowanie powinna zostać połączona z odpowiedzią @ Kohányi Róbert, ponieważ oba są najlepszym podejściem do zadania.
PaulB

15

Witamy w 2020, oto odpowiedź w Pythonie / 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}")

Znalezienie odpowiedzi zajęło mi zbyt dużo czasu i było to takie proste.


4

Dziwię się, że nie ma takiej prostej drogi 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

Spróbuj poszukać zaktualizowanej metody , ponieważ Boto3 może się od czasu do czasu zmieniać. Użyłem 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

Przez który interfejs? Korzystając z interfejsu REST, po prostu wysyłasz usunięcie :

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

Poprzez interfejs 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>

Jeśli używasz biblioteki Pythona, takiej jak boto , powinna ona udostępniać funkcję „usuń”, na przykład delete_key().


tak, używam tej biblioteki Pythona, ale czy to usunie plik? czy powinienem to zrobić w ten sposób: k.key = 'images / anon-images / small /' + filename k.delete_key () czy to poprawne? proszę daj mi znać.
Suhail

@Suhail: Nie korzystałem z tej biblioteki, ale ze źródła, które podłączyłem, tak naprawdę robi to DELETEpołączenie przez interfejs REST. Więc tak, pomimo nazwy „delete_key” (co, zgadzam się, jest niejasne), tak naprawdę usuwa obiekt, do którego odwołuje się klucz.
TJ Crowder

1
A co z usunięciem wielu plików ze wspólnym prefiksem w nazwie? Czy S3 pozwala na zbiorcze usuwanie w takim przypadku, czy też usuwanie ich jeden po drugim (co jest powolne) jest koniecznością?
Illarion Kovalchuk,

@Shaman: Nie jestem ekspertem od S3, ale o ile wiem , możesz usunąć tylko określony plik. Ale prawdopodobnie chcesz zadać to pytanie jako pytanie, aby zwrócić na to uwagę ekspertów S3.
TJ Crowder,

Zaraz po skomentowaniu tutaj dodałem takie pytanie. Ma jeszcze 2 widoki :)
Illarion Kovalchuk

2

Najprostszym sposobem na to jest:

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

1

Na razie rozwiązałem ten problem za pomocą narzędzia Linux s3cmd . Użyłem tego w Pythonie w ten sposób:

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

1
Wywołanie podpowłoki w celu komunikacji z S3 nie jest dokładnie pythonowe (biblioteka lub bezpośrednia transakcja HTTP byłaby bardziej elegancka), ale nadal działa. Myślę, że nie zasługuje na złą opinię. +1.
Randall Cook

1

Pomogło mi, spróbuj.

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

możesz to zrobić używając aws cli: https://aws.amazon.com/cli/ i jakiegoś polecenia unixowego.

te polecenia aws cli powinny działać:

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

jeśli chcesz uwzględnić podfoldery, powinieneś dodać flagę --recursive

lub za pomocą poleceń 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'

wyjaśnienie:

  1. lista wszystkich plików w zasobniku --pipe ->
  2. pobierz czwarty parametr (jest to nazwa pliku) --pipe -> // możesz go zastąpić poleceniem linux, aby pasował do twojego wzorca
  3. uruchom skrypt usuwania za pomocą aws cli

1

jeśli próbujesz usunąć plik przy użyciu własnej lokalnej konsoli hosta, możesz spróbować uruchomić ten skrypt Pythona zakładając, że już przypisałeś swój identyfikator dostępu i tajny klucz w systemie

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

Poniższe zadziałały dla mnie (w oparciu o przykład dla modelu Django, ale prawie sam możesz użyć kodu deletemetody).

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

Poniżej znajduje się fragment kodu, którego możesz użyć do usunięcia zasobnika,

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

spróbuj tego kodu

import boto3   
s3 = boto3.client('s3')
s3.delete_object(Bucket="s3bucketname", Key="s3filepath")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.