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 文件