【问题标题】:Difficulty in executing boto3 S3 copy function using aws lambda使用 aws lambda 执行 boto3 S3 复制功能时遇到困难
【发布时间】:2020-07-07 15:44:55
【问题描述】:

这里是场景。我有一个 S3 存储桶(例如 daily-data-input),其中每日文件将被写入特定文件夹(例如 S3://daily-data-input/data/test/)。每当在“test”文件夹下写入文件时,也应将副本写入同一存储桶中的“test_copy”文件夹。如果“test_copy”不存在,则应该创建它。

我使用了 S3 事件通知并将其附加到一个 lambda 函数(使用 python 3.7),该函数将检查“test_copy”键是否存在,如果不存在则将被创建。我能够成功创建“test_copy”文件夹,但无法通过 boto3 制作 S3 副本。

以下是供您参考的代码:

import boto3
import os
import botocore
s3 = boto3.resource('s3')
s3_cli=boto3.client('s3')

def lambda_handler(event, context):

    bucket_name = event ['Records'][0]['s3']['bucket']['name']
    bucket_key = event['Records'][0]['s3']['object']['key']
    file = (os.path.basename(bucket_key))
    source_key_path = (os.path.dirname(bucket_key))
    target_keypath = source_key_path+'_'+'copy'+'/'
    target_bucket_key = target_keypath+file
    copy_source = {'Bucket': bucket_name, 'Key': bucket_key}
    try:
        s3.Object(bucket_name, target_keypath).load()
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == "404":
            # Create the key
            print ("Creating target _copy folder")
            s3_cli.put_object(Bucket=bucket_name,Key=target_keypath)
            #copy the file
            #s3.copy_object(Bucket=bucket_name, Key=target_bucket_key, CopySource=copy_source)
        else:
            print ("Something went wrong!!")
    else:
        print ("Key exists!!")
        # s3.copy_object(Bucket=bucket_name, Key=target_bucket_key, CopySource=copy_source) 

我尝试了 s3.copy_object、s3_cli.meta.client.copy、bucket.copy(),但它们都不起作用。如果我做错了什么,请告诉我。

【问题讨论】:

  • “不工作”是什么意思?遇到任何错误?
  • 无需检查test_copy文件夹是否存在并创建。你不需要它。只需从data/test/cat.png 复制到data/test_copy/cat.png
  • 尝试以下等效项:s3.Object('mybucket','data/test_copy/cat.png').copy_from(CopySource='mybucket/data/test/cat.png')
  • @jarmod 好的。所以如果key不存在,会自动创建。?

标签: python-3.x amazon-web-services amazon-s3 aws-lambda boto3


【解决方案1】:

这是在存储桶中复制 S3 中的对象的一种简单方法:

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

bucket = 'mybucket'
src_key = 'data/test/cat.png'
dest_key = 'data/test_copy/cat.png'

s3.Object(bucket, dest_key).copy_from(CopySource=f'{bucket}/{src_key}')

这是做同样事情的另一种较低级别的方法:

import boto3
s3 = boto3.client('s3')

bucket = 'mybucket'
src_key = 'data/test/cat.png'
dest_key = 'data/test_copy/cat.png'

s3client.copy_object(Bucket=bucket, CopySource={'Bucket':bucket,'Key':src_key}, Key=dest_key)

【讨论】:

  • 我试过“s3.Object(bucket, dest_key).copy_from(CopySource=f'{bucket}/{src_key}')”,这是用文件创建多个_Copy文件夹。
  • 您的意思大概是_copy(小写),但这似乎不太可能。请检查您在 copy_from 调用中用于插值的变量的值。重置您的测试存储桶并使用一个上传的文件从头开始重试。会发生什么?
  • 是的。它正在使用目标文件创建多个 _copy 文件夹。这是格式:test_copy、test_copy_copy、test_copy_copy_copy 等。我不确定错误在哪里,但一定会按照建议尝试。
  • 您的 Lambda 函数由原始 test 文件和您刚刚复制的 test_copy 文件触发。这导致了test_copy_copy 文件。这会再次触发 Lambda,每次重复添加 _copy。那很好笑。您的 Lambda 函数只能在 data/test/ 前缀上触发。更改 S3 触发器。
  • 你是对的。目前,该事件与“所有对象创建事件”相关联,前缀为 data/。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-04
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
相关资源
最近更新 更多