【问题标题】:How to read csv file from s3 bucket in AWS Lambda?如何从 AWS Lambda 的 s3 存储桶中读取 csv 文件?
【发布时间】:2019-11-12 21:52:12
【问题描述】:

我正在尝试读取上传到 s3 存储桶上的 csv 文件的内容。为此,我从触发 lambda 函数的事件中获取存储桶名称和文件密钥,并逐行读取。这是我的代码:

import json
import os
import boto3
import csv

def lambda_handler(event,  context):
    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        file_key = record['s3']['object']['key']
        s3 = boto3.client('s3')
        csvfile = s3.get_object(Bucket=bucket, Key=file_key)
        csvcontent = csvfile['Body'].read().split(b'\n')
        data = []
        with open(csvfile['Body'], 'r') as csv_file:
          csv_file = csv.DictReader(csv_file)
          data = list(csv_file)

我在 CloudWatch 上遇到的确切错误是:

[ERROR] TypeError: expected str, bytes or os.PathLike object, not list
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 19, in lambda_handler
    with open(csvcontent, 'r') as csv_file:

有人可以帮我解决这个问题吗?感谢您提供的任何帮助,因为我是 lambda 新手

【问题讨论】:

  • csvcontent 已包含您的数据。无需打开文件。 csvcontent 实际上是一个可以解析的字符串(行)列表。

标签: python amazon-s3 aws-lambda boto3 aws-serverless


【解决方案1】:

要从 s3 存储桶中正确获取 CSV 文件数据,并且易于检索以下代码的索引格式,对我有很大帮助:

key = 'key-name'
bucket = 'bucket-name'
s3_resource = boto3.resource('s3')
s3_object = s3_resource.Object(bucket, key)

data = s3_object.get()['Body'].read().decode('utf-8').splitlines()

lines = csv.reader(data)
headers = next(lines)
print('headers: %s' %(headers))
for line in lines:
    #print complete line
    print(line)
    #print index wise
    print(line[0], line[1])

【讨论】:

  • 您知道如何在 lambda 中获取该 csv 文件作为数据框吗?
  • 请注意,如果您仍然使用 utf-8 得到奇怪的字符,请尝试使用 utf-8-sig,因为它将字节顺序标记读取为信息而不是字符串。见stackoverflow.com/questions/57152985/…
【解决方案2】:
csvfile = s3.get_object(Bucket=bucket, Key=file_key)
csvcontent = csvfile['Body'].read().split(b'\n')

您已经在此处检索了文件内容并将其拆分为行。我不知道你为什么要再次尝试open,你可以将csvcontent 传递给你的阅读器:

csv_data = csv.DictReader(csvcontent)

【讨论】:

  • 对于小型 csv 是的。对于大文件,此代码会占用所有内存并卡住
  • 在你的情况下是 s3 boto3.client("s3") 还是 boto3.resource("s3") ?
【解决方案3】:

csvfile['Body'] 类型是StreamingBody,所以不能使用open xx with

此代码已从流中读取所有数据。

csvcontent = csvfile['Body'].read().split(b'\n')

所以 jsut 解析该行以获得更有用的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    相关资源
    最近更新 更多