![](/img/trans.png)
[英]how to copy files and folders from one S3 bucket to another S3 using python boto3
[英]How to append multiple files into one in Amazon's s3 using Python and boto3?
我在亞馬遜的 S3 中有一個名為test-bucket
。 在這個存儲桶中,json 文件如下所示:
test-bucket
| continent
| country
| <filename>.json
本質上,文件名是continent/country/name/
。 在每個國家/地區,大約有 100k 個文件,每個文件包含一個字典,如下所示:
{"data":"more data", "even more data":"more data", "other data":"other other data"}
不同的文件有不同的長度。 我需要做的是將所有這些文件編譯成一個文件,然后將該文件重新上傳到 s3。 簡單的解決方案是使用 boto3 下載所有文件,將它們讀入 Python,然后使用以下腳本附加它們:
import json
def append_to_file(data, filename):
with open(filename, "a") as f:
json.dump(record, f)
f.write("\n")
但是,我不知道所有文件名(名稱是時間戳)。 如何讀取文件夾中的所有文件,例如Asia/China/*
,然后將它們附加到文件中,文件名是國家?
最理想的是,我不想將所有文件下載到本地存儲中。 如果我可以將這些文件加載到內存中,那就太好了。
編輯:讓事情更清楚。 s3 上的文件不存儲在文件夾中,文件路徑只是設置為看起來像一個文件夾。 所有文件都存儲在test-bucket
。
答案很簡單。 您可以使用過濾器列出存儲桶中的所有文件,將其過濾到前綴中的“子目錄”。 如果你事先有一個大洲和國家的列表,那么你可以減少返回的列表。 返回的列表將具有前綴,因此您可以將對象名稱列表過濾為您想要的名稱。
s3 = boto3.resource('s3')
bucket_obj = s3.Bucket(bucketname)
all_s3keys = list(obj.key for obj in bucket_obj.objects.filter(Prefix=job_prefix))
if file_pat:
filtered_s3keys = [key for key in all_s3keys if bool(re.search(file_pat, key))]
else:
filtered_s3keys = all_s3keys
上面的代碼將返回所有文件,以及它們在存儲桶中的完整前綴,不包括提供的前綴。 因此,如果您提供 prefix='Asia/China/',那么它將僅提供具有該前綴的文件列表。 在某些情況下,在使用完整前綴訪問文件之前,我會采取第二步並過濾該“子目錄”中的文件名。
第二步是下載所有文件:
with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_THREADS) as executor:
executor.map(lambda s3key: bucket_obj.download_file(s3key, local_filepath, Config=CUSTOM_CONFIG),
filtered_s3keys)
為簡單起見,我跳過了這一事實,即代碼為每個下載的文件生成一個 local_filepath,因此它是您真正想要的文件以及您想要它的位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.