2016-05-12 6 views

Antwort

2

Es ist nicht "Verzeichnis" in S3. Dieses Trennzeichen "/" ist nur ein Teil des Objektnamens, deshalb verfügt Boto nicht über solche Funktionen. Schreiben Sie entweder ein Skript, um damit umzugehen, oder verwenden Sie Tools von Drittanbietern.

AWS customerapps zeigen s3browser, die solche beliebige Verzeichniskopierfunktionalität bieten. Die typische kostenlose Version erzeugt nur zwei Threads, um die Datei zu verschieben, die kostenpflichtige Version ermöglicht es Ihnen, mehr Threads anzugeben und schneller zu laufen.

Oder Sie schreiben einfach Skript und verwenden s3.client.copy_object, um die Datei unter einem anderen Namen zu kopieren, und löschen Sie sie anschließend. z.B.

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 

** WICHTIGE HINWEISE **: list_object nur zurückgeben maximal 1000 Schlüssel pro Eintrag, MaxKey nicht die Grenze ändern. Also müssen Sie list_objects_v2 verwenden und prüfen, ob NextContinuationToken zurückgegeben wird, um sicherzustellen, dass das Objekt mehr ist, wiederholen Sie es, bis es erschöpft ist.

+0

Ich weiß alles in S3 ist wie Schlüssel Wert Dinge. Ich möchte Objekte Inhalt rekursiv von einem Teil des Schlüssels zu einem anderen kopieren. –

+0

Kannst du ein anderes Python-Paket vorschlagen, um es zu erreichen? –

+0

Einfach s3browser ausprobieren. Ansonsten müssen Sie ein eigenes Skript schreiben. – mootmoot

1

Nur versuchen, auf vorherige Antwort zu bauen:

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 

Oder Sie eine auch die einfache awscli verwenden, die auf EC2/emr Maschinen standardmäßig installiert ist.

import subprocess 

cmd='aws s3 cp '+path+' '+uploadUrl+' --recursive' 
p=subprocess.Popen(cmd, shell=True,stdout=subprocess.PIPE) 
p.communicate()