我是使用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?
感谢您的时间。
答案 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();
....
}
答案 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