Python脚本合并AWS S3中多JSON文件失败,result.extend未正常工作
解决S3多JSON文件合并时
result.extend未生效的问题 问题根源分析
你的代码没达到预期效果,主要有这几个核心问题:
- S3前缀格式错误:
prefix_path开头加了斜杠/myfolder/myfile/,但S3的对象键没有根目录概念,开头的斜杠会被当成键的一部分,导致list_objects_v2匹配不到目标文件夹下的文件,最终拿到的文件列表为空或不符合预期。 - JSON结构适配问题:如果单个JSON文件里是单个对象(比如
{"name": "test"})而非数组([{"name": "test"}]),result.extend(content_json)会把字典的键当成元素塞进列表,完全不是你要的合并效果。 - 未处理S3列表分页:当前缀下文件超过1000个时,
list_objects_v2会返回分页结果,当前代码只取第一页,直接遗漏后续文件。
修正后的代码
import boto3 import json s3 = boto3.client('s3') def conjsondocuments(bucket, prefix, output_file): result = [] # 处理S3列表分页,获取前缀下所有文件 paginator = s3.get_paginator('list_objects_v2') page_iterator = paginator.paginate(Bucket=bucket, Prefix=prefix) json_file_keys = [] for page in page_iterator: json_file_keys.extend([obj['Key'] for obj in page.get('Contents', [])]) for key in json_file_keys: # 跳过S3的文件夹占位对象(键以/结尾) if key.endswith('/'): continue data = s3.get_object(Bucket=bucket, Key=key) content = data['Body'].read().decode("utf-8") if content: try: content_json = json.loads(content) # 根据JSON结构选择合并方式:数组用extend,单个对象用append if isinstance(content_json, list): result.extend(content_json) else: result.append(content_json) except json.JSONDecodeError as e: print(f"解析{key}的JSON失败: {e}") else: print(f"{key}内容为空") with open(output_file, 'w') as output: json.dump(result, output, indent=2) print(f"合并后的JSON已保存到本地路径: {output_file}") if __name__ == "__main__": bucket_name = 'myawss3' # 去掉前缀开头的斜杠,符合S3键命名规则 prefix_path = 'myfolder/myfile/' output_json_file = 'conjsondoc.json' conjsondocuments(bucket_name, prefix_path, output_json_file)
关键修复说明
- 适配S3分页机制:用
paginator遍历所有分页结果,确保不会漏掉超过1000个的文件。 - 修正前缀格式:移除前缀开头的斜杠,让S3能正确匹配目标文件夹下的所有文件。
- 灵活处理JSON结构:判断每个文件的解析结果是列表还是单个对象,分别用
extend或append,保证合并结果符合下游应用需求。 - 跳过无效对象:自动过滤S3的文件夹占位符,避免读取空内容或非JSON文件。
内容的提问来源于stack exchange,提问作者paone
相关产品推荐
相关产品推荐

