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

Python Lambda实现S3跨桶JSON文件修改传输及只读报错解决

错误原因

AWS Lambda 运行时仅 /tmp 目录开放写入权限,其余目录均为只读。原代码直接在函数工作根目录写入awsEC2Pricebook.json、尝试写入部署包内./assets/路径下的文件,必然触发只读文件系统报错。除此之外原代码还有3个逻辑问题:

  • 缺失uuid模块导入,运行时会抛模块不存在错误
  • 参考UUID文件存放在Lambda部署包内,本身是只读的,就算绕开权限写入,实例回收后修改也会丢失,下次冷启动还是会加载初始版本
  • 处理完成后没有调用S3上传接口,无法实现文件跨桶传输的需求
修复后完整代码

以下代码完全跳过不必要的本地文件写入,直接在内存中完成JSON处理后上传到目标S3桶,从根源避免文件系统权限问题,同时修复了原有逻辑缺陷:

import json
import boto3
import uuid

s3_client = boto3.client('s3')
# 替换为你的实际配置
TARGET_BUCKET = "替换为你的目标S3存储桶名称"
REFERENCE_UUID_S3_KEY = "assets/referenceUUIDAwsEC2Prices.json"

def lambda_handler(event, context):
    # 从触发事件获取源桶和待处理文件信息
    source_bucket = event['Records'][0]['s3']['bucket']['name']
    source_file_key = event['Records'][0]['s3']['object']['key']
    
    # 读取源S3存储桶中的价格JSON文件
    price_file_resp = s3_client.get_object(Bucket=source_bucket, Key=source_file_key)
    price_content = price_file_resp['Body'].read().decode("utf-8")
    ec2_price_data = json.loads(price_content)
    
    # 从目标S3桶拉取最新的参考UUID映射文件,避免使用部署包内的只读旧版本
    ref_file_resp = s3_client.get_object(Bucket=TARGET_BUCKET, Key=REFERENCE_UUID_S3_KEY)
    ref_content = ref_file_resp['Body'].read().decode("utf-8")
    uuid_ref_data = json.loads(ref_content)

    # 原有ID匹配、生成逻辑
    for item in ec2_price_data:
        grouping_code = f"{item['region']}_{item['operatingSystem']}_{item['name']}"
        match_id = None
        for ref_item in uuid_ref_data:
            if grouping_code == ref_item['groupingCode']:
                match_id = ref_item['uniqueID']
                break
        if match_id:
            item['id'] = match_id
        else:
            new_id = str(uuid.uuid4())
            item['id'] = new_id
            uuid_ref_data.append({
                "groupingCode": grouping_code,
                "uniqueID": new_id
            })
    
    # 上传处理完成的价格文件到目标S3桶
    s3_client.put_object(
        Bucket=TARGET_BUCKET,
        Key="awsEC2Pricebook.json",
        Body=json.dumps(ec2_price_data).encode("utf-8"),
        ContentType="application/json"
    )
    
    # 上传更新后的UUID映射文件回S3做持久化
    s3_client.put_object(
        Bucket=TARGET_BUCKET,
        Key=REFERENCE_UUID_S3_KEY,
        Body=json.dumps(uuid_ref_data).encode("utf-8"),
        ContentType="application/json"
    )
    
    return {"statusCode": 200, "body": "Processing completed"}
配置注意事项
  • 提前给Lambda绑定的IAM执行角色添加对应S3权限:对源存储桶允许s3:GetObject操作,对目标存储桶允许s3:GetObject、s3:PutObject操作
  • 首次运行前,在目标存储桶的对应路径上传初始版本的referenceUUIDAwsEC2Prices.json文件,文件内容为[]即可,后续运行会自动追加新的UUID映射
  • 如果业务必须生成本地临时文件,所有文件路径必须添加/tmp/前缀,例如/tmp/awsEC2Pricebook.json,除此路径外任何位置的写入操作都会触发只读报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:45:44