最简单的lambda函数,用于将文件从一个s3存储桶复制到另一个存储桶

时间:2018-01-16 16:55:23

标签: python amazon-web-services amazon-s3 lambda aws-lambda

我是使用AWS的总菜鸟。我试图让一个非常简单和基本的操作工作。我想要做的是,当一个文件被上传到一个s3存储桶时,我希望该上传触发一个Lambda函数,该函数将该文件复制到另一个存储桶。

我去了AWS管理控制台,在us-west2服务器上创建了一个名为" test-bucket-3x1"用作我的"来源"桶和另一个名为" test-bucket-3x2"作为我的目的地'桶。创建这些存储桶时,我没有更改或修改任何设置。

在Lambda控制台中,我为' test-bucket-3x1'创建了一个s3触发器,更改了'事件类型'到" ObjectCreatedByPut",并且没有更改任何其他设置。

这是我的实际lamda_function代码:

import boto3
import json
s3 = boto3.resource('s3')


def lambda_handler(event, context):
    bucket = s3.Bucket('test-bucket-3x1')
    dest_bucket = s3.Bucket('test-bucket-3x2')
    print(bucket)
    print(dest_bucket)

    for obj in bucket.objects():
        dest_key = obj.key
        print(dest_key)
        s3.Object(dest_bucket.name, dest_key).copy_from(CopySource = {'Bucket': obj.bucket_name, 'Key': obj.key})

当我使用基本" HelloWorld"测试此功能时从AWS Lambda控制台获得测试,我收到了这个"

{
  "errorMessage": "'s3.Bucket.objectsCollectionManager' object is not callable",
  "errorType": "TypeError",
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      12,
      "lambda_handler",
      "for obj in bucket.objects():"
    ]
  ]
}

我需要对代码进行哪些更改才能将文件上传到test-bucket-3x1,触发lambda函数并将文件复制到test-bucket-3x2?

感谢您的时间。

3 个答案:

答案 0 :(得分:1)

我将从蓝图开始 s3-get-object 有关从蓝图创建 lambda 的更多信息,请使用 this page:

这是上面蓝图的代码:

console.log('Loading function');

const aws = require('aws-sdk');

const s3 = new aws.S3({ apiVersion: '2006-03-01' });


exports.handler = async (event, context) => {
    //console.log('Received event:', JSON.stringify(event, null, 2));

    // Get the object from the event and show its content type
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
        Bucket: bucket,
        Key: key,
    };
    try {
        const { ContentType } = await s3.getObject(params).promise();
        console.log('CONTENT TYPE:', ContentType);
        return ContentType;
    } catch (err) {
        console.log(err);
        const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
        console.log(message);
        throw new Error(message);
    }
};

然后你需要更新上面的代码,不仅要获取对象信息,还要复制和删除源,为此你可以参考这个答案:

const moveAndDeleteFile = async (file,inputfolder,targetfolder) => {
    const s3 = new AWS.S3();

    const copyparams = {
        Bucket : bucketname,
        CopySource : bucketname + "/" + inputfolder + "/" + file, 
        Key : targetfolder + "/" + file
    };

    await s3.copyObject(copyparams).promise();

    const deleteparams = {
        Bucket : bucketname,
        Key : inputfolder + "/" + file
    };

    await s3.deleteObject(deleteparams).promise();
    ....
}

来源:How to copy the object from s3 to s3 using node.js

答案 1 :(得分:0)

for object in source_bucket.objects.all():
    print(object)
    sourceObject = { 'Bucket' : 'bucketName', 'Key': object}
    destination_bucket.copy(sourceObject, object)

答案 2 :(得分:0)

您确实应该使用event方法中的lambda_handler()来获取文件[path | prefix | uri]并仅处理该文件,因为您的事件是在文件{{ 1}}:

put

关于直接从s3Bucket打开文件的其他问题,我建议检查smart_open,以确保“种类”像本地文件系统一样处理s3Bucket:

def lambda_handler(event, context):
    ...

    if event and event['Records']:
        for record in event['Records']:
            source_key = record['s3']['object']['key']

            ... # do something with the key: key-prefix/filename.ext