将文件上传到 GCS,如果存在则跳过 python
Upload files to GCS, skip if existed using python
我有一个名为 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
的文件。它将跳过上传此路径中的现有文件。直到遇到一个不存在的文件,它会上传该文件并覆盖所有目录的其他文件。
我期望它只上传尚不存在的特定文件,而不会覆盖其他文件。
我尽力解释了...请帮忙。
如果您查看 documentation,您可以在 blob
的名称 属性 上看到
The name of the blob. This corresponds to the unique path of the object in the bucket.
这意味着该值不仅是文件名,而且是完全限定路径+名称path/to/file.csv
如果循环,请检查文件名(例如 file.csv
)是否包含在 blob 路径中。考虑这种情况
path/to/file.csv
path/to/to/file.csv
如果您测试 file.csv
存在,则两个 blob 都将 return 为真。
要解决您的问题,您需要
- 要么比较target_path+file_name和blob.name
的严格相等
- 或者在您的“if”中包含一个附加条件,以包含要检查的存储桶路径以及文件名。
我有一个名为 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
的文件。它将跳过上传此路径中的现有文件。直到遇到一个不存在的文件,它会上传该文件并覆盖所有目录的其他文件。
我期望它只上传尚不存在的特定文件,而不会覆盖其他文件。
我尽力解释了...请帮忙。
如果您查看 documentation,您可以在 blob
的名称 属性 上看到The name of the blob. This corresponds to the unique path of the object in the bucket.
这意味着该值不仅是文件名,而且是完全限定路径+名称path/to/file.csv
如果循环,请检查文件名(例如 file.csv
)是否包含在 blob 路径中。考虑这种情况
path/to/file.csv
path/to/to/file.csv
如果您测试 file.csv
存在,则两个 blob 都将 return 为真。
要解决您的问题,您需要
- 要么比较target_path+file_name和blob.name 的严格相等
- 或者在您的“if”中包含一个附加条件,以包含要检查的存储桶路径以及文件名。