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

Python 最简单的lambda函数,用于将文件从一个s3存储桶复制到另一个s3存储桶,python,amazon-web-services,amazon-s3,aws-lambda,Python,Amazon Web Services,Amazon S3,Aws Lambda,我完全不想和AWS合作。我正在尝试一个非常简单和基本的操作。我想做的是,当一个文件被上传到一个s3存储桶时,我希望上传触发一个Lambda函数,该函数将该文件复制到另一个存储桶 我转到AWS管理控制台,在us-west2服务器上创建了一个名为“test-bucket-3x1”的s3存储桶,用作我的“源”存储桶,另一个名为“test-bucket-3x2”的存储桶用作我的“目标”存储桶。创建这些存储桶时,我没有更改或修改任何设置 在Lambda控制台中,我为“test-bucket-3x1”创建了

我完全不想和AWS合作。我正在尝试一个非常简单和基本的操作。我想做的是,当一个文件被上传到一个s3存储桶时,我希望上传触发一个Lambda函数,该函数将该文件复制到另一个存储桶

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

在Lambda控制台中,我为“test-bucket-3x1”创建了一个s3触发器,将“event type”更改为“ObjectCreatedByPut”,并且没有更改任何其他设置

这是我实际的lamda_函数代码:

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})
当我使用AWS Lambda控制台提供的基本“HelloWorld”测试测试此函数时,我收到以下消息“

我需要对代码进行哪些更改,以便在将文件上载到test-bucket-3x1时触发lambda函数并将文件复制到test-bucket-3x2


谢谢您的时间。

您应该真正使用
lambda_handler()
方法中的
事件来获取文件[path | prefix | uri]并仅处理该文件,因为您的事件是在文件
放入bucket时触发的:

for object in source_bucket.objects.all():
    print(object)
    sourceObject = { 'Bucket' : 'bucketName', 'Key': object}
    destination_bucket.copy(sourceObject, object)
def lambda_处理程序(事件、上下文):
...
如果事件和事件[‘记录’]:
对于事件['Records']中的记录:
source_key=记录['s3']['object']['key']
…#对键执行一些操作:key prefix/filename.ext
对于直接从s3Bucket打开文件的附加问题,我建议检查“某种”处理s3Bucket就像处理本地文件系统一样:

从熊猫导入数据帧,读取
从智能打开导入打开
def read_as_csv(文件uri:str):->DataFrame
将open(file_uri)作为f:
返回读取csv(f,名称=列名称)

我将从蓝图开始
s3get对象
有关从蓝图创建lambda的详细信息,请使用:

这是上面蓝图的代码:

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();
    ....
}

来源:

你不应该对bucket.objects.all()中的obj使用
,而不是对bucket.objects()中的obj使用
。请参阅此链接:“object不可调用”-你正在尝试对其进行迭代。我想你可能正在寻找使用
bucket.objects.all()
它创建了一个iterableThanks来寻求帮助。这看起来很傻,但对我来说真的很有用。我可以去cloudwatch日志,开始了解
事件和
上下文对象实际上是什么。在相关说明中,是否可以通过lambda打开/使用s3存储桶中的文件?例如,我可以吗将csv加载到pandas dataframe中,操作dataframe,返回操作过的dataframe,然后将其上载到我的目标bucket?这会像使用事件处理程序放入类似
df=pd.read_excel(['Records']['bucket']['object']['key']这样简单吗
?请注意,如果您真的要将所有新对象从一个存储桶复制到另一个存储桶,AWS中有一个S3存储桶复制功能。请不要仅将代码作为答案发布,还要解释代码的作用以及它如何解决问题。这将使您的答案更有价值,更有可能吸引更多人投票。
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();
    ....
}