як видалити файли з відра amazon s3?


91

Мені потрібно написати код на python, який видалить необхідний файл із відра Amazon s3. Я можу підключитися до відра Amazon s3, а також зберегти файли, але як я можу видалити файл?


Яку (якщо є) бібліотеку Python ви використовуєте для підтримки S3? Або ви прямуєте до інтерфейсів REST або SOAP у коді Python?
TJ Crowder,

1
Я використовую бібліотеку Python boto.s3
Suhail

Відповіді:


94

Використовуючи boto3(на даний час версія 1.4.4) use S3.Object.delete().

import boto3

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

1
Якщо об'єкта немає, чи видасть він помилку?
Akash Tantri

2
@AkashTantri Я особисто не пробував, але документ каже, що видаляє нульову версію (якщо вона є) [...] Якщо не існує нульової версії, Amazon S3 не видаляє жодних об'єктів. Тож я здогадуюсь, що це не призведе до помилки. Якщо ви s3.Object('existing-bucket', 'bogus-key').delete()випадково спробуєте (просто зробіть щось подібне і подивіться, що станеться. Також спробуйте s3.Object('bogus-bucket', 'bogus-key').delete().
Kohányi Róbert

Працює як шарм, ось справжня сила python
yunus

@yunus це серйозний коментар?
Генрі Хенрінсон,

Чи your-keyозначає тут справжнє ім'я файлу your-bucketна S3?
Underoos

91

знайшов ще один спосіб зробити це за допомогою бото:

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
Якщо ви хочете видалити ВСЕ у відрі, ви можете зробити:for x in b.list(): b.delete_key(x.key)
jontsai

19
Мені подобається, як це виявляється в моєму досьєbucket.list()
Артур Сапек

Щоб цей фрагмент коду працював, як представлено, вам потрібно буде імпортувати Bucketі Keyтеж. Як у:from boto.s3.connection import S3Connection, Bucket, Key
Нік Чаммас

Я отримую, >>> 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.connectionбудь ласка, оновіть відповідь на boto3
Harry Moreno

1
розібрався і написав рішення harrymoreno.com/2017/04/24/…
Гаррі Морено

74

Використовуючи Python boto3 SDK (і припускаючи, що облікові дані налаштовані для AWS), наступне видалить вказаний об’єкт у сегменті:

import boto3

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

6
@Rob Документація boto3 вводить в оману. він створить маркер видалення, якщо об'єкт має версію. В іншому випадку об’єкт буде видалено.
jarmod

1
Чисто і просто. Це може бути прийнятою відповіддю, і її неодмінно слід поєднати з відповіддю @ Kohányi Róbert, оскільки обидва варіанти є найкращим підходом для цього завдання.
PaulB

15

Ласкаво просимо до 2020 року ось відповідь у 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}")

Мені знадобилося занадто багато часу, щоб знайти відповідь, і це було так просто, як це.


4

Я здивований, що це не такий простий спосіб 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

Спробуйте шукати оновлений метод , оскільки Boto3 може час від часу змінюватися. Я використав 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

Через який інтерфейс? За допомогою інтерфейсу REST ви просто надсилаєте видалення :

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

Через інтерфейс 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>

Якщо ви використовуєте бібліотеку Python, таку як boto , вона повинна мати функцію "видалення", наприклад delete_key().


так, я використовую цю бібліотеку python, але чи буде це видалити файл? чи слід робити це таким чином: k.key = 'images / anon-images / small /' + ім'я файлу k.delete_key () це правильно? будь ласка, дай мені знати.
Suhail

@Suhail: Я не користувався цією бібліотекою, але з джерела, яке я зв’язав, насправді він робить DELETEвиклик через інтерфейс REST. Тож так, незважаючи на назву "delete_key" (що, на мою думку, незрозуміле), це справді видалення об'єкта, на який посилається ключ.
TJ Crowder,

1
А як щодо видалення безлічі файлів із загальним префіксом у назві? Чи дозволяє S3 масове видалення для такого випадку, або видалення їх по одному (що повільно) є обов’язковим?
Ілларіон Ковальчук

@Shaman: Я не експерт S3, але, наскільки мені відомо , ви можете видалити лише певний файл. Але ви, мабуть, хочете насправді поставити це запитання, щоб воно привернуло увагу експертів S3.
TJ Crowder

Відразу після коментарів я додав таке запитання. У нього ще 2 перегляди :)
Ілларіон Ковальчук

2

Найпростіший спосіб зробити це:

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

1

Наразі я вирішив проблему за допомогою утиліти Linux s3cmd . Я використовував це так у Python:

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

1
Не зовсім пітонічно викликати підшарку для спілкування з S3 (бібліотека або пряма транзакція HTTP була б більш елегантною), але вона все одно працює. Я не думаю, що це заслуговує проти. +1.
Randall Cook

1

Мені це вдалося, спробуйте.

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

Ви можете зробити це за допомогою aws cli: https://aws.amazon.com/cli/ та деякої команди unix.

Команди aws cli повинні працювати:

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

якщо ви хочете включити підпапки, вам слід додати прапор --recursive

або за допомогою команд 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'

пояснення:

  1. перерахувати всі файли у відрі --pipe ->
  2. отримати четвертий параметр (його назва файлу) --pipe -> // ви можете замінити його командою linux, щоб вона відповідала вашому шаблону
  3. запустити скрипт видалення за допомогою aws cli - -

1

якщо ви намагаєтесь видалити файл за допомогою власної локальної консолі хосту, ви можете спробувати запустити цей скрипт python, припускаючи, що ви вже призначили свій ідентифікатор доступу та секретний ключ у системі

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

Для мене працювало наступне (на основі прикладу для моделі Django, але ви можете в значній мірі використовувати код deleteметоду самостійно).

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

Нижче наведено фрагмент коду, за допомогою якого можна видалити сегмент,

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()

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.