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

AWS Lambda Python脚本读取S3 CSV全量行但写入输出行数缺失

AWS Lambda CSV写入S3行数缺失问题解决方案

核心成因

  • 最核心原因:文件上传操作时机错误。当前代码将upload_file方法放在with open上下文块内部,此时文件仍处于打开状态,Python与操作系统的IO缓冲区中还有部分未刷入磁盘的内容,上传的文件仅包含已经写入磁盘的部分,直接导致行数缺失。
  • 第二大原因:代码缩进错误。你提供的原始代码中,输出文件读取计数、return语句均位于lambda_handler函数外部,Lambda运行时仅会执行函数内的逻辑,外部代码会在冷启动阶段执行,此时要么还未生成输出文件,要么读取的是上一次运行的旧文件,导致计数结果异常。
  • 小概率原因:/tmp目录空间不足,不过2万多行的CSV文件远小于Lambda默认提供的512MB临时空间,该情况可以优先排除。

排查步骤

  • 检查代码缩进:确认文件上传、输出计数、返回值逻辑全部在lambda_handler函数内部。
  • 在CloudWatch日志中打印上传前本地临时文件的大小,以及S3上输出文件的元数据大小,若两者不一致即可确认是上传时文件未完全写入导致的问题。
  • 可在上传前先调用file.flush() + os.fsync(file.fileno())强制刷入缓冲区,验证行数是否恢复正常。

解决方法

修正后的代码如下:

import json
import os
import io
import boto3
import csv
import time

def lambda_handler(event, context):
    s3 = boto3.resource(u's3')
    s3_object_in = s3.Object('MYBUCKET', 'INPUT.csv')

    data_in = s3_object_in.get()['Body'].read().decode('utf-8').splitlines()
    lines = csv.reader(data_in, delimiter=',')

    lambda_path = "/tmp/temp.csv"
    i_in=0
    # 写入本地临时文件
    with open(lambda_path, 'w+', encoding="utf-8") as file:
        for line in lines:
            file.write(str(i_in)+ '\n')
            i_in += 1
    # 退出with块后文件已自动关闭,缓冲区全部刷入磁盘,此时再上传
    s3.Bucket('MYBUCKET').upload_file(lambda_path, 'out.csv')
    
    # 计数输出文件行数,逻辑放在函数内部
    s3_object_out = s3.Object('MYBUCKET', 'out.csv')
    data_out = s3_object_out.get()['Body'].read().decode('utf-8').splitlines()    
    lines_out = csv.reader(data_out)
    i_out=0
    for line in lines_out:
        i_out += 1

    return {
       'count_in': i_in,
       'count_out': i_out
      }

修正点说明:

  1. 将S3上传操作移动到with open块外部,确保文件关闭、内容完全写入磁盘后再上传
  2. 调整代码缩进,将输出文件计数、return语句全部放在lambda_handler函数内部
  3. 移除冗余的file.close()语句,with上下文管理器会自动处理文件关闭

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:24:02