2016-05-12 118 views

答えて

2

にB/X/*のようなキーから再帰的にすべてのオブジェクトをコピーしたいB1/X/* をS3の「ディレクトリ」。それらの "/"セパレータはオブジェクト名の一部に過ぎません。そのため、botoにはそのような機能がありません。それに対処するためのスクリプトを書くか、サードパーティのツールを使用してください。

AWS customerapps show s3browserこのような任意のディレクトリコピー機能を提供します。典型的なフリーバージョンでは、ファイルを移動するために2つのスレッドしか生成されません。有料バージョンでは、より多くのスレッドを指定してより速く実行できます。

スクリプトを作成してs3.client.copy_objectを使用してファイルを別の名前にコピーした後で削除してください。例えば

import boto3 
s3 = boto3.client("s3") 
# list_objects_v2() give more info 

more_objects=True 
found_token = True 
while more_objects : 
    if found_token : 
    response= s3.list_objects_v2(
     Bucket="mybucket", 
     Prefix="B1/x/", 
     Delimiter="/") 
    else: 
    response= s3.list_objects_v2(
     Bucket="mybucket", 
     ContinuationToken=found_token, 
     Prefix="B1/x/", 
     Delimiter="/") 
    # use copy_object or copy_from 
    for source in object_list["Contents"]: 
    raw_name = source["Key"].split("/")[-1] 
    new_name = "new_structure/{}".format(raw_name) 
    s3.copy_object(
     .... 
    )  
    # Now check there is more objects to list 
    if "NextContinuationToken" in response: 
     found_token = response["NextContinuationToken"] 
     more_objects = True 
    else: 
     more_objects = False 

**重要事項**:list_objectは1リストあたり最大1000個のキーしか返さないため、MaxKeyは制限を変更しません。したがって、list_objects_v2を使用して、NextContinuationTokenが返されているかどうかをチェックして、より多くのオブジェクトであることを確認し、使い果たされるまで繰り返す必要があります。

+0

私はs3のすべてがキーバリューのようなものだと知っています。 私は、オブジェクトのコンテンツをキーの一部から別の部分に再帰的にコピーしたいと思っています。 –

+0

これを達成するための他のPythonパッケージを提案できますか? –

+0

s3browserに試してみてください。それ以外の場合は、独自のスクリプトを作成する必要があります。 – mootmoot

1

ただ、前の回答に構築しようとしている:

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

def copyFolderFromS3(self,pathFrom, bucketTo, locationTo): 
     response = {} 
     response['status'] = 'failed' 
     getBucket = path.split('/')[2] 
     location = '/'.join(path.split('/')[3:]) 
     if path.startswith('s3://'): 
     copy_source = { 'Bucket': getBucket, 'Key': location } 
     uploadKey = locationTo 
     self.recursiveCopyFolderToS3(copy_source,bucketTo,uploadKey) 


def recursiveCopyFolderToS3(self,src,uplB,uplK): 
    more_objects=True 
    found_token = True 
    while more_objects : 
    if found_token : 
     response = self.s3.list_objects_v2(
     Bucket=src['Bucket'], 
     Prefix=src['Key'], 
     Delimiter="/") 
    else: 
     response = self.s3.list_objects_v2(
     Bucket=src['Bucket'], 
     ContinuationToken=found_token, 
     Prefix=src['Key'], 
     Delimiter="/") 
    for source in response["Contents"]: 
     raw_name = source["Key"].split("/")[-1] 
     raw_name = raw_name 
     new_name = os.path.join(uplK,raw_name) 
     if raw_name.endswith('_$folder$'): 
      src["Key"] = source["Key"].replace('_$folder$','/') 
      new_name = new_name.replace('_$folder$','') 
      self.recursiveCopyFolderToS3(src,uplB,new_name) 
     else: 
      src['Key'] = source["Key"] 
      self.s3.copy_object(CopySource=src,Bucket=uplB,Key=new_name)  
      if "NextContinuationToken" in response: 
       found_token = response["NextContinuationToken"] 
       more_objects = True 
      else: 
       more_objects = False 

それともまたEC2/EMRのマシンにインストールデフォルトでは、単純なawscliを使用しています。

import subprocess 

cmd='aws s3 cp '+path+' '+uploadUrl+' --recursive' 
p=subprocess.Popen(cmd, shell=True,stdout=subprocess.PIPE) 
p.communicate() 
関連する問題