【问题标题】:Upload files to GCS, skip if existed using python将文件上传到 GCS,如果存在则使用 python 跳过
【发布时间】:2021-09-20 20:16:46
【问题描述】:

我有一个名为 my-gcs 的 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 的文件。它将跳过上传此路径中的现有文件。直到遇到一个不存在的文件,它才会上传该文件并覆盖所有目录的其他文件。

我期望它只上传尚不存在的特定文件,而不会覆盖其他文件。

我已尽力解释...请帮忙。

【问题讨论】:

  • 不是解决方案,但请注意 Cloud Storage 中不存在目录。这意味着在有条件地调用upload_local_directory_to_gcs() 之前不要检查目录是否存在。对于每个文件,您都列出了所有对象。相反,列出对象,保存它们,然后在内存中比较每个对象。您的代码适用于一个小存储桶,但一旦它变大,时间会急剧增加。

标签: python google-cloud-platform google-cloud-storage


【解决方案1】:

如果您查看documentation,您可以在 blob 的 Name 属性上看到它

blob 的名称。这对应于桶中对象的唯一路径。

这意味着值不仅是文件名,而是完全限定路径+名称path/to/file.csv

如果您的循环,请检查文件名(例如file.csv)是否包含在 blob 路径中。考虑这种情况

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

如果你的测试是 file.csv 存在,两个 blob 都将返回 true。

要解决您的问题,您需要

  • 比较 target_path + file_name 和 blob.name 的严格相等性
  • 或者在您的“if”中包含一个附加条件,以包含除了文件名之外要检查的存储桶路径。

【讨论】:

  • 您好,感谢您的建议!我按照您建议的方式使用严格相等进行了修复。不敢相信我错过了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
  • 2019-09-11
  • 2022-11-15
  • 2019-10-26
  • 1970-01-01
  • 2021-10-09
相关资源
最近更新 更多