Boto3 получает последнюю версию префикса / вложенной папки

#python #amazon-web-services #amazon-s3 #boto3 #boto

#python #amazon-веб-сервисы #amazon-s3 #boto3 #бото

Вопрос:

Я хотел бы получить последнюю версию префикса S3 на основе времени последнего изменения или времени создания. Не уверен, есть ли элегантный способ сделать это. Что я получаю до сих пор, так это:

 s3 = boto3.client("s3")
response = s3.list_objects_v2(Bucket="bucket_name", Delimiter="/", Prefix="abc/")['CommonPrefixes']

for obj in response:
   print obj['Prefix']

"bucket_name/abc/20190420"
"bucket_name/abc/20190421"
"bucket_name/abc/20190422"
"bucket_name/abc/20190423"
  

Допустим, каждый день мы создаем префикс и ключи в папке, каков наилучший способ получить последнюю версию префикса, которая является «bucket_name / abc / 20190423», в данном случае предполагая, что сегодня 2019-04-23? Кроме того, не предполагайте, что имя префикса всегда является числом или датой, которые мы легко разбираем и сортируем, это также могут быть случайные буквы или слова.

Упорядочены ли префиксы из ответа изначально на основе некоторого измененного времени или времени создания? Если нет, то какой самый элегантный способ получить самую последнюю версию префикса?

Ответ №1:

Я собираюсь предположить, что под «последним префиксом» вы подразумеваете «префикс для объекта, созданного последним».

Пожалуйста, обратите внимание, что префиксы фактически не создаются. Скорее, они являются просто частью Key (имени файла) объекта.

Получение самого последнего созданного объекта относительно просто. Вы могли бы использовать AWS CLI:

 aws s3api list-objects --bucket my-bucket --query 'sort_by(Contents, amp;LastModified)[-1].Key' --output text
  

Затем вы можете манипулировать выводом с помощью сценариев оболочки (вплоть до последней косой черты).

В Python вы могли бы использовать:

 import boto3

s3_client = boto3.client('s3', region_name='ap-southeast-2')

response = s3_client.list_objects_v2(Bucket='my-bucket')

# Get the key of the object with the highest LastModified date
latest_object = max(response['Contents'], key = lambda obj: obj['LastModified'])['Key']

# Print prefix of latest object
if '/' in latest_object:
    print(latest_object[:latest_object.rfind('/')]  )
  

Комментарии:

1. Спасибо, понял, что для путей s3 не существует концепции папок, а объекты основаны на ключе на фактическом уровне ключа. Спасибо за помощь.

Ответ №2:

Не уверен, как работает boto3, но вы могли бы провести простое сравнение, используя функции split и max .

 def getDateValue(prefixString):
    return int(prefixString.split("/")[2])

s3 = boto3.client("s3")
response = s3.list_objects_v2(Bucket="bucket_name", Delimiter="/", Prefix="abc/")['CommonPrefixes']

latest = max(response, key=getDateValue)
  

Функция getDateValue принимает префикс, разбивает его на основе символа «/», получает третью часть (дату) и преобразует ее в целое число. max Функция применяет это к каждому префиксу и возвращает тот, который имеет наибольшее значение (т. Е. Последнюю дату)

Комментарии:

1. что, если имя префикса не имеет шаблона, это случайные буквы, создаваемые каждый день вместо даты и времени? Я обновил вопрос, чтобы упомянуть о возможности этого.

2. В этом случае это не сработало бы. Он будет работать только с текстом, подобным тексту в вашем примере, в котором конечная часть префикса может быть преобразована в целое число.