Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Amazon';s s3使用Python和boto3?_Python_Json_Python 3.x_Amazon S3_Boto3 - Fatal编程技术网

如何在Amazon';s s3使用Python和boto3?

如何在Amazon';s s3使用Python和boto3?,python,json,python-3.x,amazon-s3,boto3,Python,Json,Python 3.x,Amazon S3,Boto3,我在Amazon的S3中有一个bucket,名为testbucket。在这个bucket中,json文件如下所示: test-bucket | continent | country | <filename>.json {"data":"more data", "even more data":"more data", "other data":"other other data"} 不同的文件有不同的长度。我需要做的是将所有这些文

我在Amazon的S3中有一个bucket,名为
testbucket
。在这个bucket中,json文件如下所示:

test-bucket
    | continent
        | country
            | <filename>.json
{"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上的文件不存储在文件夹中,文件路径只是设置为看起来像文件夹。所有文件都存储在
testbucket

下,答案相当简单。您可以使用过滤器列出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

上面的代码将返回所有文件,它们的完整前缀在bucket中,仅限于提供的前缀。所以,如果您提供前缀='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)

为简单起见,我跳过了显示以下事实:代码为下载的每个文件生成一个本地文件路径,因此它是您真正想要的文件,并且位于您想要的位置。

您可以修改我的旧答案,以读取特定前缀内的所有文件。您可以启动一个小实例来运行该工作。