首页 > 解决方案 > 根据“LastModified”将所有文件从一个 S3 位置移动到另一个(相同的存储桶)

问题描述

我正在尝试从这篇文章中复制第二个答案

问题:

需要根据“LastModified”将所有文件从位置 A 移动到位置 B。但是原始帖子上的代码是从桶到桶的。我需要将它从一个文件夹移动到同一个存储桶中的另一个文件夹。

代码:

source_prefix = 'path_to_source/'
target_prefix = 'path_to_target/'

# create s3 client
s3_client = boto3.client('s3')

# create a reusable paginator
paginator = s3_client.get_paginator('list_objects_v2')

# create a PageIterator from paginator
page_iterator = paginator.paginate(Bucket=bucket, Prefix=source_prefix)

# loop through each object, look for files older than 1 hr from current time 
for page in page_iterator:
    for object in page['Contents']:
        if object['LastModified'] < datetime.now().astimezone() - timedelta(hours=1):
            print(f"Moving {object['Key']}")
            
            # Copy object
            s3_client.copy_object(
                Bucket=bucket,
                Prefix=target_prefix,
                Key=object['Key'],
                CopySource={'Bucket':bucket, 'Prefix':source_prefix, 'Key':object['Key']}
             )

最后,我在复制对象中添加了“Prefix=target_prefix”。但我收到以下错误:

botocore.exceptions.ParamValidationError:参数验证失败:输入中的未知参数:“前缀”,必须是以下之一:

问题: 如何遍历对象并从一个前缀位置复制到另一个前缀位置?

标签: pythonamazon-web-servicesamazon-s3boto3

解决方案


boto3copy_object()调用不接受Prefix参数。

Key包含创建对象的完整路径。实际上,它成为新对象的 Key(包括完整路径)。

我假设您的要求是:如果对象超过一小时,则将对象从源路径“移动”到目标路径(在同一存储桶内)。

(请注意,S3 中没有“移动”命令——相反,它需要复制和删除。)

这是一些可以执行此操作的代码:

import boto3
from datetime import datetime, timedelta

BUCKET = 'my-bucket'
INPUT_PATH = 'input/'
OUTPUT_PATH = 'output/'

s3_client = boto3.client('s3')

# Create a reusable Paginator
paginator = s3_client.get_paginator('list_objects_v2')

# Create a PageIterator from the Paginator
page_iterator = paginator.paginate(Bucket=BUCKET,Prefix=INPUT_PATH)

# Loop through each object, looking for ones older than a given time period
for page in page_iterator:
    if 'Contents' in page:
        for object in page['Contents']:
            if object['LastModified'] < datetime.now().astimezone() - timedelta(hours=1):   # <-- Change time period here
                
                # Strip off input path and add output path
                source_key = object['Key']
                target_key = OUTPUT_PATH + source_key[len(INPUT_PATH):] 
                print(f"Moving {source_key} to {target_key}")

                # Copy object
                s3_client.copy_object(
                    Bucket=BUCKET,
                    Key=target_key,
                    CopySource={'Bucket':BUCKET, 'Key':source_key}
                )

                # Delete original object
                s3_client.delete_object(Bucket=BUCKET, Key=source_key)

推荐阅读