You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:使用Python在AWS S3中合并JSON文件,解决内容覆盖问题

解决S3中合并两个JSON文件避免覆盖的问题

我明白你现在碰到的问题了——想要把S3桶里的patienta.json和patient_b.json两个文件的内容合并成单个patient.json,但之前的代码会直接覆盖目标文件内容,根本达不到合并的效果对吧?别着急,我给你整理了完整的解决方案,包括调整后的代码和关键说明:

核心思路

要实现合并而不是覆盖,关键得先把两个源文件的内容都读出来,合并成一个新的JSON结构之后,再上传到S3的patient.json里(毕竟S3是对象存储,上传同名文件本身就是覆盖,但我们上传的是合并后的完整内容,就不会丢失任何数据了)。

完整Lambda代码

#!/usr/bin/python
# -*- coding: utf-8 -*-
import boto3
import json
from decimal import Decimal

# 处理Decimal类型的JSON编码器(如果你的JSON数据来自DynamoDB这类服务,大概率需要这个)
class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, Decimal):
            # 把Decimal转成整数或浮点数,避免序列化报错
            return int(o) if o % 1 == 0 else float(o)
        return super().default(o)

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    # 从触发事件里获取S3桶名称
    bucket = event['Records'][0]['s3']['bucket']['name']
    
    # 定义要处理的源文件和目标文件名
    source_files = ['patienta.json', 'patient_b.json']
    target_file = 'patient.json'
    
    # 用来存储合并后的数据,这里默认用数组格式,你可以按需调整
    merged_data = []
    
    # 逐个读取并处理源文件
    for file_name in source_files:
        try:
            # 从S3获取文件内容
            response = s3_client.get_object(Bucket=bucket, Key=file_name)
            # 读取并解析JSON数据
            file_content = response['Body'].read().decode('utf-8')
            json_data = json.loads(file_content, parse_float=Decimal, parse_int=Decimal)
            
            # 根据源文件的JSON结构做合并:
            # 如果是单个患者对象,就添加到数组;如果已经是数组,就直接合并数组
            if isinstance(json_data, dict):
                merged_data.append(json_data)
            elif isinstance(json_data, list):
                merged_data.extend(json_data)
                
        except s3_client.exceptions.NoSuchKey:
            # 处理文件不存在的情况,避免整个函数崩溃
            print(f"警告:桶 {bucket} 里找不到文件 {file_name}")
            continue
    
    # 把合并后的数据转成JSON字符串
    merged_json = json.dumps(merged_data, cls=DecimalEncoder)
    
    # 上传合并后的内容到目标文件
    s3_client.put_object(
        Bucket=bucket,
        Key=target_file,
        Body=merged_json,
        ContentType='application/json'
    )
    
    return {
        'statusCode': 200,
        'body': json.dumps(f"搞定!已经合并两个文件并上传到 {target_file}")
    }

关键细节说明

  • Decimal编码器:如果你的JSON数据是从DynamoDB导出的,里面会有Decimal类型的数据,这个编码器能帮你把它转成普通的数字类型,避免JSON序列化失败。如果你的数据里没有这种类型,可以直接删掉这个类,以及json.dumps里的cls=DecimalEncoder参数。
  • 合并逻辑自定义:上面的代码默认把两个文件的内容放到一个数组里(比如两个患者对象变成一个患者列表)。如果你想把两个对象的属性合并成一个对象(比如把两个文件里的字段整合到同一个患者对象里),可以把合并部分改成这样:
    merged_data = {}
    for file_name in source_files:
        # ...读取解析代码不变...
        if isinstance(json_data, dict):
            merged_data.update(json_data)
    
  • 权限注意事项:别忘了给你的Lambda执行角色加上S3:GetObject和S3:PutObject的权限,不然会出现权限不足的报错。
  • 容错处理:代码里加了文件不存在的捕获,就算其中一个源文件丢了,另一个文件的内容也能正常合并进去,不会直接崩溃。

内容的提问来源于stack exchange,提问作者Anand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:07:39