web-dev-qa-db-ja.com

BotoでS3ファイルをダウンロードする

ユーザーがS3バケットに保存されているファイルをダウンロードできるアプリをセットアップしようとしています。バケットを設定して正しいファイルを取得できますが、ダウンロードされないため、次のエラーが発生します:No such file or directory: 'media/user_1/imageName.jpg'なぜですか?これは比較的簡単な問題のように思えますが、私はそれを完全に理解できないようです。画像を正しく削除できるので、正しい画像を識別できます。

これが私のviews.pyです

def download(request, project_id=None):
    conn = S3Connection('AWS_BUCKET_KEY', 'AWS_SECRET_KEY')
    b = Bucket(conn, 'BUCKET_NAME')
    k = Key(b)
    instance = get_object_or_404(Project, id=project_id)
    k.key = 'media/'+str(instance.image)
    k.get_contents_to_filename(str(k.key))
    return redirect("/dashboard/")
6
pepper5319

問題は、存在しないローカルディレクトリにダウンロードしていることですmedia/user1)。次のいずれかを行う必要があります。

  • 最初にローカルマシンにディレクトリを作成します
  • フルパスではなくファイル名を使用してください
  • フルパスを使用しますが、スラッシュ(/)別の文字を使用-これにより、ディレクトリを作成しなくてもファイル名の一意性が保証されます

最後のオプションは、次の方法で実現できます。

k.get_contents_to_filename(str(k.key).replace('/', '_'))

参照: S3バケットからすべてのファイルをダウンロードするBoto

11
John Rotenstein

Boto3を使用したファイルのダウンロードは非常に簡単です。このコードを使用する前に、システムレベルでAWS認証情報を設定してください。

client = boto3.client('s3')

// if your bucket name is mybucket and the file path is test/abc.txt
// then the Bucket='mybucket' Prefix='test'

resp = client.list_objects_v2(Bucket="<your bucket name>", Prefix="<prefix of the s3 folder>") 

for obj in resp['Contents']:
    key = obj['Key']
    //to read s3 file contents as String
    response = client.get_object(Bucket="<your bucket name>",
                         Key=key)
    print(response['Body'].read().decode('utf-8'))

    //to download the file to local
    client.download_file('<your bucket name>', key, key.replace('test',''))

replaceは、ローカルでs3ファイル名を使用してファイルを検索することです。置換しない場合は、「test /abc.txt」として保存しようとします。

2
import os
import boto3
import json

s3 = boto3.resource('s3', aws_access_key_id="AKIAxxxxxxxxxxxxJWB",
                    aws_secret_access_key="LV0+vsaxxxxxxxxxxxxxxxxxxxxxry0/LjxZkN")
my_bucket = s3.Bucket('s3testing')

# download file into current directory
for s3_object in my_bucket.objects.all():
    # Need to split s3_object.key into path and file name, else it will give error file not found.
    path, filename = os.path.split(s3_object.key)
    my_bucket.download_file(s3_object.key, filename)
0