AWS Lambda Python 读取所有行但不写入所有行

Posted

技术标签:

【中文标题】AWS Lambda Python 读取所有行但不写入所有行【英文标题】:AWS Lambda Python reads all lines but don't write all 【发布时间】:2021-12-08 16:03:54 【问题描述】:

我有一个在 AWS Lambda 中运行的 Python 3.8 脚本。

应该使用 csv.reader(data_in, delimiter=',') 从 S3 逐行读取文件,并逐行写入同一存储桶中的另一个 CSV 文件。

显然它工作正常,但是当我查看输出文件时,它的行数总是更少。

这是脚本:

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"
    with open(lambda_path, 'w+', encoding="utf-8") as file:
        i_in=0
        for line in lines:
            file.write(str(i_in)+ '\n')
            i_in += 1
        s3.Bucket('MYBUCKET').upload_file(lambda_path, 'out.csv')
    file.close()


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
  

此代码在测试时返回以下响应:

回应


  "count_in": 25428,
  "count_out": 25057

因此,通过查看 i_in,代码显然会一直运行到输入文件的最后一行(实际上有 25428 行)。但是 file.write 函数在第 25057 行停止。

输出文件使用从 0 开始到 25056 结束的连续计数器写入

有什么想法吗?

我正在运行 1024 MB RAM,10 分钟超时

【问题讨论】:

您的 CSV 文件有多大?我知道 lambda 对 tmp/ 文件夹中的文件有存储限制,所以我想知道是否可以。 您应该在上下文管理器代码完成后执行upload_file,而不是在with open(...) as file 代码部分内。此外,您正在为 temp.csv 文件使用上下文管理器,因此您不应显式关闭它。 如果您想避免写入临时文件,您也可以尝试将数据写入内存,例如像BytesIO 对象,然后将该数据直接上传到 S3。然后你可以读回你保存的数据并再次测试计数。 【参考方案1】:

以下代码有两个问题:

with open(lambda_path, 'w+', encoding="utf-8") as file:
    i_in=0
    for line in lines:
        file.write(str(i_in)+ '\n')
        i_in += 1
    s3.Bucket('MYBUCKET').upload_file(lambda_path, 'out.csv')
file.close()

具体来说,这两个问题是:

    文件正在上传到 S3,但仍在 with 上下文管理器中,因此文件可能未完全写入磁盘 with 上下文管理器会自动关闭文件,因此不需要file.close()

代码应该这样写:

with open(lambda_path, 'w+', encoding="utf-8") as file:
    i_in=0
    for line in lines:
        file.write(str(i_in)+ '\n')
        i_in += 1

s3.Bucket('MYBUCKET').upload_file(lambda_path, 'out.csv')

更多详情请见Context Managers。

【讨论】:

以上是关于AWS Lambda Python 读取所有行但不写入所有行的主要内容,如果未能解决你的问题,请参考以下文章

使用 AWS Lambda (Python 3) 读取存储在 S3 中的 Parquet 文件

使用 Python 在 AWS Glue 中打开和读取文件

如果通过验证,AWS lambda 读取 zip 文件执行验证并解压缩到 s3 存储桶

AWS lambda 函数 python/pyspark

jqGrid 生成行但不显示任何数据

复选标记检查行但不检查对象