如何使用 Lambda 将文件从一个文件夹移动到同一 AWS S3 存储桶中的另一个文件夹?
How to move a File from One folder to Another Folder in the same AWS S3 bucket using Lambda?
我正在尝试在 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
,无需任何手动干预
如何实现?
I was hoping to use Lambda function's triggers to do this but I feel, Lambda triggers at the Root directory level and can not use it at the Folder Level.
这不是真的。 S3 没有文件夹的概念。您可以使用过滤器前缀在任何“级别”触发,即 prefix -> "Landing/"
and/or 后缀(例如“.jpg”)。
S3 触发器将调用 lambda 并以新对象作为输入传递事件。然后只需使用您熟悉的任何语言,并使用任何可用的 AWS SDK(.Net、Java、python 等...)中的 s3 复制内置函数复制到目的地。
示例:
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
我觉得相对路径的概念可以解决你的问题。 这是解决您的问题的代码片段,使用名为 s3pathlib 的库,一个 objective-oriented 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,
)
如果你想要更高级的路径操作,你可以参考这个document。 S3Path.change(new_abspath, new_dirpath, new_dirname, new_basename, new_fname, new_ext)
将是您需要知道的最重要的一个。
我正在尝试在 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
,无需任何手动干预
如何实现?
I was hoping to use Lambda function's triggers to do this but I feel, Lambda triggers at the Root directory level and can not use it at the Folder Level.
这不是真的。 S3 没有文件夹的概念。您可以使用过滤器前缀在任何“级别”触发,即 prefix -> "Landing/"
and/or 后缀(例如“.jpg”)。
S3 触发器将调用 lambda 并以新对象作为输入传递事件。然后只需使用您熟悉的任何语言,并使用任何可用的 AWS SDK(.Net、Java、python 等...)中的 s3 复制内置函数复制到目的地。
示例:
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
我觉得相对路径的概念可以解决你的问题。 这是解决您的问题的代码片段,使用名为 s3pathlib 的库,一个 objective-oriented 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,
)
如果你想要更高级的路径操作,你可以参考这个document。 S3Path.change(new_abspath, new_dirpath, new_dirname, new_basename, new_fname, new_ext)
将是您需要知道的最重要的一个。