Прочитайте последний файл из Google Cloud Storage Bucket, используя функцию Cloud - PullRequest
2 голосов
/ 01 ноября 2019

Проблема, с которой я сталкиваюсь, заключается в том, что Cloud Storage сортирует вновь добавленные файлы лексикографически (в алфавитном порядке), в то время как я читаю файл с индексом 0 в корзине Cloud Storage, используя его клиентскую библиотеку python в Cloud Functions (функция облаканеобходимо как часть моего проекта) и поместить данные в BigQuery, который отлично работает для меня, но вновь добавленный файл не всегда отображается с индексом 0.

Потоковые файлы поступают в мое ведро каждый день с разнымираз. Имя файла такое же (data-2019-10-18T14_20_00.000Z-2019-10-18T14_25_00.txt), но поле даты и времени в имени файла отличается в каждом новом добавленном файле.

Как настроить этот код Python для чтения последнего добавленного файла в хранилище Cloud Storage при каждом запуске облачной функции?

files = bucket.list_blobs()
fileList = [file.name for file in files if '.' in file.name]
blob = bucket.blob(fileList[0])   #reading file placed at index 0 in bucket

Ответы [ 2 ]

3 голосов
/ 01 ноября 2019

Если у вас есть облачная функция, запускаемая по HTTP, вы можете заменить ее на функцию, которая использует Google Cloud Storage Triggers . Если это уже было так, вам нужно только воспользоваться этим преимуществом.

Каждый раз, когда запускается функция, вы можете проверить тип события и делать с данными все что угодно, например:

from google.cloud import storage

storage_client = storage.Client()

def hello_gcs_generic(data, context):
    """Background Cloud Function to be triggered by Cloud Storage.
       check more in https://cloud.google.com/functions/docs/calling/storage#functions-calling-storage-python
    """

    if context.event_type == storage.notification.OBJECT_FINALIZE_EVENT_TYPE:

        print('Created: {}'.format(data['timeCreated'])) #this here for illustration purposes
        print('Updated: {}'.format(data['updated']))

        blob = storage_client.get_bucket(data['bucket']).get_blob(data['name']) 

        #TODO whatever else needed with blob

Таким образом, вам все равно, когда объект был создан. Вы знаете, что при создании код вашей клиентской библиотеки выбирает соответствующий большой двоичный объект, и вы делаете с ним все, что хотите.

0 голосов
/ 02 ноября 2019

Если ваша цель - обработать каждый (или большинство) из загруженных файлов, ответ @ fhenrique - лучший подход.

Но если ваша обработка довольно скудна по сравнению со скоростью, с которойфайлы загружаются (или просто, если ваше требование не позволяет вам переключиться на предложенный триггер облачного хранилища), тогда вам нужно более внимательно посмотреть, почему ваше ожидание найти самый последний загруженный файл в позиции индекса 0 не соответствует,

Первая причина, которая приходит на ум, - это соглашение об именовании файлов. Например, давайте предположим 2 таких файла: data-2019-10-18T14_20_00.000Z-2019-10-18T14_25_00.txt и data-2019-10-18T14_25_00.000Z-2019-10-18T14_30_00.txt. Их лексикографический порядок будет следующим:

['data-2019-10-18T14_20_00.000Z-2019-10-18T14_25_00.txt',
 'data-2019-10-18T14_25_00.000Z-2019-10-18T14_30_00.txt']

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

Несколько других возможных причин / причин для рассмотрения (попробуйте напечатать fileList, чтобы подтвердить / опровергнуть эти теории):

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

  • список возвращенных файлов фактически не лексикографически отсортирован (по какой-либо причине),Я вижу сортировку, упомянутую в Список объектов , но не в документации по Storage Client API. Явная сортировка fileList перед выбором файла по индексу -1 должна позаботиться об этом, если необходимо.

  • с файлами в этом сегменте, которые не следуют упомянутому правилу именования (дляпо любой причине) - любой такой файл с именем, помещающим его после последнего загруженного файла, полностью нарушит ваш алгоритм. Для защиты от такого случая вы можете использовать необязательные аргументы prefix и delimiter для bucket.list_blobs(), чтобы отфильтровать результаты по мере необходимости. Из вышеупомянутого документа API:

  • префикс (str) - (необязательно) префикс, используемый для фильтрации больших объектов.

  • delimiter (str) - (Необязательно) Delimiter, используемый с префиксом для эмуляции иерархии.

Такая фильтрация также может быть полезна для ограничения количества записей, которые выпопасть в список, основываясь на текущей дате / времени, что может значительно ускорить выполнение вашей функции, особенно если загружено много таких файлов (ваше предложение по именованию предполагает, что их может быть много)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...