Использование AWS Lambda и boto3 для добавления новых строк в объекты текстового файла в S3 - PullRequest
0 голосов
/ 25 июня 2018

Я пытаюсь использовать лямбда-функцию python для добавления текстового файла с новой строкой к объекту, хранящемуся в S3.Поскольку объекты, хранящиеся в S3, являются неизменяемыми, вы должны сначала загрузить файл в '/ tmp /', затем изменить его, а затем загрузить новую версию обратно в S3.Мой код добавляет данные, но не добавляет их с новой строкой.

BUCKET_NAME = 'mybucket' 
KEY = 'test.txt'
s3 = boto3.resource('s3')

def lambda_handler(event, context):
    try:
        s3.Object(BUCKET_NAME, KEY).download_file('/tmp/test.txt')
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == "404":
            print("The object does not exist.")
        else:
            raise
    with open('/tmp/test.txt', 'a') as fd:
        fd.write("this is a new string\n")


    s3.meta.client.upload_file('/tmp/test.txt', BUCKET_NAME, KEY)

К файлу всегда добавляется новая строка, но никогда не добавляется новая строка.Любые идеи?

ОБНОВЛЕНИЕ: Эта проблема не возникает на машинах Linux или на Mac.Лямбда-функции выполняются на контейнерах linux, что означает, что файл в / tmp / сохраняется как текстовый файл в формате Unix.Некоторые приложения Windows не будут отображать разрывы строк в текстовых файлах, отформатированных в Unix, как это было здесь.Я тупой.

Ответы [ 2 ]

0 голосов
/ 24 июля 2019

Хороший пост!Просто корректировка. Вам следует изменить порядок LOCAL_FILE и KEY в параметрах метода download_file.Правильный синтаксис:

obj=s3.Bucket(BUCKET_NAME).download_file(KEY,LOCAL_FILE)

Также было бы хорошо, если бы мы удалили локальный файл в случае, если файл не найден в корзине.потому что если мы не удаляем локальный файл (если он существует, очевидно), мы можем добавить новую строку в уже существующий локальный файл.С помощью этой функции:

def remove_local_file(filePath):
import os
     # As file at filePath is deleted now, so we should check if file exists or not not before deleting them
    if os.path.exists(filePath):
        os.remove(filePath)
    else:
        print("Can not delete the file as it doesn't exists")

конечный код, начинающийся с 'try', может выглядеть следующим образом:

try:
    obj=s3.Bucket(BUCKET_NAME).download_file(KEY,LOCAL_FILE)
except ClientError as e:
    if e.response['Error']['Code'] == "404":
        print("The object does not exist.")
        remove_local_file(LOCAL_FILE)
    else:
        raise
with open(LOCAL_FILE, 'a') as fd:
    fd.write("this is a new string\n")

s3.meta.client.upload_file(LOCAL_FILE, BUCKET_NAME, KEY)
0 голосов
/ 26 июня 2018

Вам необходимо указать локальный путь к файлу

import boto3
import botocore
from botocore.exceptions import ClientError

BUCKET_NAME = 'mybucket'
KEY = 'test.txt'
LOCAL_FILE = '/tmp/test.txt'
s3 = boto3.resource('s3')

def lambda_handler(event, context):
    try:
        obj=s3.Bucket(BUCKET_NAME).download_file(LOCAL_FILE, KEY)
    except ClientError as e:
        if e.response['Error']['Code'] == "404":
            print("The object does not exist.")
        else:
            raise
    with open('/tmp/test.txt', 'a') as fd:
        fd.write("this is a new string\n")


    s3.meta.client.upload_file(LOCAL_FILE, BUCKET_NAME, KEY)

Ссылка на документ Boto3: http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Bucket.download_file

...