web-dev-qa-db-ja.com

botoでディレクトリをs3にアップロードする

私はすでにインスタンスに接続しており、pythonスクリプトから直接生成されたファイルをS3に直接アップロードします。これを試しました:

import boto
s3 = boto.connect_s3()
bucket = s3.get_bucket('alexandrabucket')
from boto.s3.key import Key
key = bucket.new_key('s0').set_contents_from_string('some content')

しかし、これはむしろディレクトリs0をmybucketにアップロードしたいのに、コンテキスト「同じコンテンツ」で新しいファイルs0を作成しています。

私もs3putを調べましたが、思い通りの結果が得られませんでした。

15
user3333539

botoライブラリ自体には、ディレクトリ全体をアップロードできるものはありません。独自のコードを記述して、os.walkなどを使用してディレクトリを走査し、botoを使用して個々のファイルをアップロードできます。

Botoにはs3putと呼ばれるコマンドラインユーティリティがあり、これを処理することも、 AWS CLIツール を使用することもできます。これには、ディレクトリ全体をアップロードしたり、ローカルディレクトリを持つS3バケット、またはその逆。

16
garnaat

次の関数を使用して、boto経由でディレクトリをs3にアップロードできます。

    def uploadDirectory(path,bucketname):
        for root,dirs,files in os.walk(path):
            for file in files:
                s3C.upload_file(os.path.join(root,file),bucketname,file)

入力として、ディレクトリへのパスとバケット名を指定します。ファイルはバケットに直接配置されます。 upload_file()関数の最後の変数を変更して、それらを「ディレクトリ」に配置します。

5
JDPTET

次のことができます。

import os
import boto3

s3_resource = boto3.resource("s3", region_name="us-east-1")

def upload_objects():
    try:
        bucket_name = "S3_Bucket_Name" #s3 bucket name
        root_path = 'D:/sample/' # local folder for upload

        my_bucket = s3_resource.Bucket(bucket_name)

        for path, subdirs, files in os.walk(root_path):
            path = path.replace("\\","/")
            directory_name = path.replace(root_path,"")
            for file in files:
                my_bucket.upload_file(os.path.join(path, file), directory_name+'/'+file)

    except Exception as err:
        print(err)

if __name__ == '__main__':
    upload_objects()
2

@JDPTETからのフィードバックに基づいて関数を作成しましたが、

  1. バケットにアップロードされないように、ローカルパス全体を削除する必要がありました。
  2. 発生するパス区切り文字の数がわからない-os.path.normpathを使用する必要があった
    def upload_folder_to_s3(s3bucket, inputDir, s3Path):
        print("Uploading results to s3 initiated...")
        print("Local Source:",inputDir)
        os.system("ls -ltR " + inputDir)

        print("Dest  S3path:",s3Path)

        try:
            for path, subdirs, files in os.walk(inputDir):
                for file in files:
                    dest_path = path.replace(inputDir,"")
                    __s3file = os.path.normpath(s3Path + '/' + dest_path + '/' + file)
                    __local_file = os.path.join(path, file)
                    print("upload : ", __local_file, " to Target: ", __s3file, end="")
                    s3bucket.upload_file(__local_file, __s3file)
                    print(" ...Success")
        except Exception as e:
            print(" ... Failed!! Quitting Upload!!")
            print(e)
            raise e

    s3 = boto3.resource('s3', region_name='us-east-1')
    s3bucket = s3.Bucket("<<s3bucket_name>>")
    upload_folder_to_s3(s3bucket, "<<Local Folder>>", "<<s3 Path>>")
0
user 923227

使用できるファイルフォームフォルダの読み取り

import boto
from boto.s3.key import Key

keyId = 'YOUR_AWS_ACCESS_KEY_ID'
sKeyId='YOUR_AWS_ACCESS_KEY_ID'
bucketName='your_bucket_name'

conn = boto.connect_s3(keyId,sKeyId)
bucket = conn.get_bucket(bucketName)
for key in bucket.list():
    print ">>>>>"+key.name
    pathV = key.name.split('/')
    if(pathV[0] == "data"):
        if(pathV[1] != ""):
            srcFileName = key.name
            filename = key.name
            filename = filename.split('/')[1]
            destFileName = "model/data/"+filename
            k = Key(bucket,srcFileName)
            k.get_contents_to_filename(destFileName)
    Elif(pathV[0] == "nlu_data"):
        if(pathV[1] != ""):
            srcFileName = key.name
            filename = key.name
            filename = filename.split('/')[1]
            destFileName = "model/nlu_data/"+filename
            k = Key(bucket,srcFileName)
            k.get_contents_to_filename(destFileName)
0
Aakash Handa