【问题标题】:How to move a File from One folder to Another Folder in the same AWS S3 bucket using Lambda?如何使用 Lambda 将文件从一个文件夹移动到同一 AWS S3 存储桶中的另一个文件夹?
【发布时间】:2022-01-24 05:05:09
【问题描述】:

我正在尝试在 S3 存储桶中的文件创建事件中自动将文件从一个文件夹移动到同一 S3 存储桶中的另一个文件夹。

我希望使用 Lambda 函数的触发器来执行此操作,但我觉得 Lambda 在根目录级别触发,不能在文件夹级别使用它。

例子:

Bucket Name: my-only-s3-bucket 
Source Folder: s3://my-only-s3-bucket/Landing 
Target Folder: s3://my-only-s3-bucket/Staging

要求:

当文件被创建或上传到源文件夹:s3://my-only-s3-bucket/Landing,它应该会自动移动到s3://my-only-s3-bucket/Staging,无需任何人工干预

如何做到这一点?

【问题讨论】:

  • 您可以在 Amazon S3 触发器上指定 Prefix 以仅调用给定前缀/文件夹的 Lambda 函数。如果您确实在根级别触发,请确保函数不会通过将对象复制到子文件夹来导致无限循环,然后该子文件夹将再次调用 Lambda 函数。只能通过移动在根级别(没有子文件夹)创建的对象来剪切此循环。但是,您需要在文件夹之间移动,所以这不是问题。
  • 谢谢。但是我有一个外部系统,它仅将 CSV 文件写入根文件夹(将其写入 S3 中的子文件夹有限制)。现在我的 Lambda 函数应该将这些从根文件夹移动到位于同一 S3 存储桶根目录中的子文件夹(因为我的组织的云管理员不喜欢创建多个存储桶的想法,我对此没有发言权)。我唯一担心的是这种递归。由于我是 AWS 新手,能否以某种方式实现?提前致谢。
  • 您可以在 Lambda 函数的开头添加一些逻辑,即 if '/' not in Key: 然后执行此操作。这表示“仅当文件名中没有 no 斜杠时才进行移动”。示例见:Moving file based on filename with Amazon S3
  • 完美,这听起来是个不错的计划。我会尝试并确认。非常感谢

标签: amazon-web-services amazon-s3 aws-lambda automation file-transfer


【解决方案1】:

我希望使用 Lambda 函数的触发器来执行此操作,但我觉得 Lambda 在根目录级别触发,不能在文件夹级别使用它。

这不是真的。 S3 没有文件夹的概念。您可以使用过滤器前缀,即prefix -> "Landing/" 和/或后缀(例如“.jpg”)在任何“级别”触发。

S3 触发器将调用 lambda 并以新对象作为输入传递事件。然后只需使用您熟悉的任何语言,并使用来自任何可用AWS SDK(.Net、Java、python 等)的内置函数 s3 copy 复制到目标位置。

示例:

def object_copied?(
  s3_client,
  source_bucket_name,
  source_key,
  target_bucket_name,
  target_key)

  return true if s3_client.copy_object(
    bucket: target_bucket_name,
    copy_source: source_bucket_name + '/' + source_key,
    key: target_key
  )
rescue StandardError => e
  puts "Error while copying object: #{e.message}"
end

【讨论】:

  • 谢谢,我试试这个
  • 我很高兴,请记住接受/支持答案,以便将来对其他人有所帮助。
【解决方案2】:

我认为相对路径的概念可以解决您的问题。 这是解决您的问题的代码 sn-p,使用名为 s3pathlib 的库,这是一个面向目标的 s3 文件系统接口。

# import the library
from s3pathlib import S3Path

# define source and target folder
source_dir = S3Path("my-only-s3-bucket/Landing/")
target_dir = S3Path("my-only-s3-bucket/Staging/")

# let's say you have a new file in Landing folder, the s3 uri is
s3_uri = "s3://my-only-s3-bucket/Landing/my-subfolder/data.csv"

# I guess you want to cut the file to the new location and delete the original one
def move_file(p_file, p_source_dir, p_target_dir):
    # validate if p_file is inside of p_source_dir
    if p_file.uri.startswith(p_source_dir.uri):
        raise ValueError

    # find new s3 path based on the relative path
    p_file_new = S3Path(
        p_target_dir, p_file.relative_to(p_source_dir)
    )

    # move
    p_file.move_to(p_file_new)

    # if you want copy you can do p_file.copy_to(p_file_new)

# then let's do your work
if __name__ == "__main__":
    move_file(
        p_file=S3Path.from_s3_uri(s3_uri),
        p_source_dir=source_dir,
        p_target_dir=target_dir,
    )

如果你想要更高级的路径操作,你可以参考这个documentS3Path.change(new_abspath, new_dirpath, new_dirname, new_basename, new_fname, new_ext) 将是您需要知道的最重要的一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2020-09-15
    • 2016-02-10
    • 2020-06-09
    • 2020-05-19
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多