Загружайте файлы в GCS, пропускайте, если они существуют, используя python

# #python #google-cloud-platform #google-cloud-storage

Вопрос:

У меня есть GCS, вызываемый my-gcs с непоследовательной вложенной папкой, такой как;

 parent-path/path1/path2/*
parent-path/path3/path4/path5/*
parent-path/path6/*
 

Файлы могут быть parquet / csv или отличаться от этого.

Это моя функция, чтобы скопировать всю папку с локального на GCS:

 def upload_local_directory_to_gcs(src_path, dest_path, data_backup, file_name):
    """
    Upload the whole directory to GCS
    """
    logger.debug("Uploading directory...")

    storage_client = storage.Client.from_service_account_json(key_path)
    bucket = storage_client.get_bucket(GCS_BUCKET)

    if os.path.isfile(src_path):
        blob = bucket.blob(os.path.join(dest_path, os.path.basename(src_path)))
        blob.upload_from_filename(src_path)
        return

    for item in glob.glob(src_path   '/*'):

        file_exist = check_file_exist(data_backup, file_name)

        if os.path.isfile(item):
            print(item)

            if file_exist is False:
                blob = bucket.blob(os.path.join(dest_path, os.path.basename(item)),
                                   chunk_size=10485760)
                blob.upload_from_filename(item)
            else:
                logger.warning("Skipping upload. File already existed")

        else:
            if file_exist is False:
                upload_local_directory_to_gcs(item, os.path.join(dest_path, os.path.basename(item)),
                                            data_backup, file_name)
            else:
                logger.warning("Skipping upload. File already existed")

 

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

 def check_file_exist(dataset, file_name):
    """
    Check if files existed
    """
    storage_client = storage.Client.from_service_account_json(key_path)
    bucket = storage_client.bucket(GCS_BUCKET)

    logger.debug("Checking if file already existed in GCS to skip upload...")

    blobs = bucket.list_blobs(prefix=f'parent-path{dataset}/')
    check_files = [blob.name for blob in blobs if file_name in blob.name] #  if '.' in blob.name

    return bool(len(check_files))
 

Однако код работает неправильно. Допустим, в этом пути parent-path/path1/path2/* уже есть файл с именем first_file.csv . Он пропустит загрузку существующего файла по этому пути. До тех пор, пока он не обнаружит файл, которого еще не существовало, он будет загружать файл и перезаписывать другие файлы для всех каталогов.

Где я ожидал, что он загрузит только определенный файл, которого еще не существовало, без перезаписи других файлов.

Я изо всех сил старался объяснить… пожалуйста, помогите.

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

1. Не решение, но обратите внимание, что каталоги не существуют в облачном хранилище. Это означает, что не проверяйте, существует ли каталог перед условным вызовом upload_local_directory_to_gcs() . Для каждого файла вы перечисляете все объекты. Вместо этого перечислите объекты, сохраните их, а затем сравните в памяти для каждого объекта. Ваш код будет работать для небольшой группы, но как только он станет большим, время резко увеличится.

Ответ №1:

Если вы посмотрите документацию, вы можете увидеть это в свойстве Name большого двоичного объекта

Название капли. Это соответствует уникальному пути объекта в корзине.

Это означает, что значение-это не только имя файла, но и полный путь имя path/to/file.csv

Если ваш цикл, вы проверяете, включено ли имя файла ( file.csv например) в путь к blob-объекту. Рассмотрим этот случай

 path/to/file.csv
path/to/to/file.csv
 

Если вы проверите file.csv , существует ли, оба больших двоичных объекта вернут значение true.

Чтобы устранить вашу проблему, вам необходимо

  • Либо сравните строгое равенство пути к цели имени файла и blob.name
  • Или включите дополнительное условие в «если», чтобы включить путь к корзине для проверки в дополнение к имени файла.

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

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