# #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. Привет, спасибо за ваше предложение! Я исправил то, что вы рекомендовали, используя строгое равенство. Не могу поверить, что я это пропустил