【问题标题】:How to write, update, and save a CSV in AWS S3 using AWS Lambda如何使用 AWS Lambda 在 AWS S3 中写入、更新和保存 CSV
【发布时间】:2020-02-06 14:51:57
【问题描述】:

我正在自动化 AWS Textract 流程,其中使用应用程序(我已经完成)将文件上传到 S3,触发 lambda 函数,将表单提取为 CSV,并将其保存在同一个文件中桶。

我只对图像中的所有文本使用了一个 Textract 公式,结果是一个 .txt 文件。以下是我的代码:

def InvokeTextract(bucketName, documentKey):
    print('Loading InvokeTextract')
    # Call Amazon Textract
    response = textract.detect_document_text(
        Document={
            'S3Object': {
                'Bucket': bucketName,
                'Name': documentKey
            }
        })

    Textractoutput = ''

    # Print detected text
    for item in response['Blocks']:
        if item['BlockType'] == 'LINE':
            Textractoutput += item['Text'] + '\n'

    return Textractoutput

def writeOutputToS3Bucket(textractData, bucketName, createdS3Document):
    print('Loading writeOutputToS3Bucket')
    generateFilePath = os.path.splitext(createdS3Document)[0] + '.txt'
    s3.put_object(Body=textractData, Bucket=bucketName, Key=generateFilePath)
    print('Generated ' + generateFilePath)


def lambda_handler(event, context):
    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    try:
        Textractoutput = InvokeTextract(bucket, key)
        writeOutputToS3Bucket(Textractoutput, bucket, key)

        return 'Processed'

这很好用,但是如果我想获得键值对,这没有帮助。所以,我尝试对 CSV 使用另一个代码。从我的本地驱动器,我能够做到这一点。以下是我的部分代码:

import trp #Local Module
import csv

doc = Document(response) #from TRP

with open('aws_doc.csv', mode='w') as aws_field_file:
    field_write = csv.writer(aws_field_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    field_write.writerow(["Key", "Value"])

    for page in doc.pages:
        for field in page.form.fields:
            # This will write it as your <key>, <value>
            field_write.writerow([field.key, field.value])

但是当我尝试使用 Lambda 进行编码时,我没有得到结果(即我的存储桶中的 CSV 文件)。我阅读了它,发现我需要创建一个 tmp 文件,但这有点不清楚。我使用下面的代码:

def lambda_handler(event, context):
    # Get the object from the event and show its content type
    bucketName = event['Records'][0]['s3']['bucket']['name']
    documentKey = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')

    #S3 client
    s3 = boto3.resource('s3')

    # Amazon Textract client
    textract = boto3.client('textract')

    # Get AWS Textract Response for Forms
    response = textract.analyze_document(
        Document={
            'S3Object': {
                'Bucket': bucketName,
                'Name': documentKey
            }
        },
        FeatureTypes = ["FORMS"])

    # Using custom trp module
    doc = Document(response)

    import csv 

    temp_csv_file = csv.writer(open("/tmp/csv_file.csv", "w+"))
    temp_csv_file.writerow(["Key", "Value"])

    for page in doc.pages:
        for field in page.form.fields:
            # This will write it as your <key>, <value>
            temp_csv_file.writerow([field.key, field.value])

    bucketName.upload_file('/tmp/csv_file.csv', 'textractData.csv')

我的代码正确吗?我是不是少了一步?

【问题讨论】:

    标签: python csv aws-lambda csv-write-stream


    【解决方案1】:

    代替

    bucketName.upload_file('/tmp/csv_file.csv', 'textractData.csv')
    

    试试

    s3.upload_file('/tmp/csv_file.csv', bucketName, 'textractData.csv')
    

    【讨论】:

    • 我想知道 csv 文件是否已保存到磁盘。您可以阅读并打印到控制台吗? (就在 bucketName.upload_file 之前)
    【解决方案2】:

    除非您需要创建临时文件,否则请尝试此操作。

    s3.put_object(Body='contents', Bucket='bucket-name', Key='outputTextFileName')

    通过如下实现使其工作:

    def writeCSV(csvData):
        body = StringIO() #because s3 require bytes or file like obj
        writer = csv.writer(body)
        for item in csvData:
            writer.writerow(item)
        csvS3 = body.getvalue()
        return csvS3
    
    contents = writeCSV('provide csv data')
    s3.put_object(Body=contents, Bucket='bucket-name', Key='outputTextFileName')
    
    • S3 必须事先使用s3 = boto3.client('s3') 定义
    • 桶必须存在于同一个 lambda 函数的区域

    【讨论】:

      猜你喜欢
      • 2018-09-16
      • 1970-01-01
      • 2021-01-27
      • 2019-07-27
      • 1970-01-01
      • 2018-06-08
      • 2017-03-04
      • 1970-01-01
      • 2018-08-03
      相关资源
      最近更新 更多