如何使用boto在两个Amazon S3存储桶之间移动文件?

问题描述 投票:19回答:7

我必须使用Python Boto API在一个存储桶之间移动文件。 (我需要它从第一个Bucket中“剪切”文件并在第二个Bucket中“粘贴”它。最好的方法是什么?

**注意:如果我有两个不同的ACCESS KEYS和SECRET KEYS,那有关系吗?

python amazon-s3 boto
7个回答
22
投票

我认为boto S3文档可以回答你的问题。

https://github.com/boto/boto/blob/develop/docs/source/s3_tut.rst

通过boto将文件从一个存储桶移动到另一个存储桶实际上是从源到目标的密钥副本,而不是从源中删除密钥。

您可以访问存储桶:

import boto

c = boto.connect_s3()
src = c.get_bucket('my_source_bucket')
dst = c.get_bucket('my_destination_bucket')

并迭代键:

for k in src.list():
    # copy stuff to your destination here
    dst.copy_key(k.key.name, src.name, k.key.name)
    # then delete the source key
    k.delete()

另见:Is it possible to copy all files from one S3 bucket to another with s3cmd?


13
投票

如果您使用的是boto3(较新的boto版本),这非常简单

import boto3
s3 = boto3.resource('s3')
copy_source = {
    'Bucket': 'mybucket',
    'Key': 'mykey'
}
s3.meta.client.copy(copy_source, 'otherbucket', 'otherkey')

(Qazxswpoi)


6
投票

对于我来说,awscli的工作速度比boto应对和删除每个键快30倍。可能是由于awscli中的多线程。如果您仍想从python脚本运行它而不从中调用shell命令,您可以尝试这样的事情:

安装awscli python包:

Docs

然后它就像这样简单:

sudo pip install awscli

2
投票

存储桶名称必须是字符串而不是存储桶对象。以下变化对我有用

import os
if os.environ.get('LC_CTYPE', '') == 'UTF-8':
    os.environ['LC_CTYPE'] = 'en_US.UTF-8'

from awscli.clidriver import create_clidriver
driver = create_clidriver()
driver.main('s3 mv source_bucket target_bucket --recursive'.split())

2
投票

如果你想

创建已存储在Amazon S3中的对象的副本。

然后for k in src.list(): dst.copy_key(k.key, src.name, k.key) 是boto3的方式。

我是怎么做到的

copy_object

1
投票

如果您有2个具有不同访问凭据的不同存储桶。将凭据相应地存储在〜/ .aws文件夹下的凭据和配置文件中。

您可以使用以下命令从具有不同凭据的一个存储桶复制对象,然后将该对象保存在具有不同凭据的另一个存储桶中:

import boto3

aws_access_key_id = ""
aws_secret_access_key = ""
bucket_from = ""
bucket_to = ""
s3 = boto3.resource(
    's3',
    aws_access_key_id=aws_access_key_id,
    aws_secret_access_key=aws_secret_access_key
)
src = s3.Bucket(bucket_from)

def move_files():
    for archive in src.objects.all():
        # filters on archive.key might be applied here

        s3.meta.client.copy_object(
            ACL='public-read',
            Bucket=bucket_to,
            CopySource={'Bucket': bucket_from, 'Key': archive.key},
            Key=archive.key
        )

move_files()

两个存储桶都不需要在ACL或存储桶策略中具有彼此的可访问性。


0
投票

这是我用来在s3存储桶的子目录中移动文件的代码

import boto3


session_src = boto3.session.Session(profile_name=<source_profile_name>)
source_s3_r = session_src.resource('s3')

session_dest = boto3.session.Session(profile_name=<dest_profile_name>)
dest_s3_r = session_dest.resource('s3')

# create a reference to source image
old_obj = source_s3_r.Object(<source_s3_bucket_name>, <prefix_path> + <key_name>)

# create a reference for destination image
new_obj = dest_s3_r.Object(<dest_s3_bucket_name>, old_obj.key)

# upload the image to destination S3 object
new_obj.put(Body=old_obj.get()['Body'].read())
© www.soinside.com 2019 - 2024. All rights reserved.