web-dev-qa-db-ja.com

boto3でmultipart_uploadを完了しますか?

これを試しました:

import boto3
from boto3.s3.transfer import TransferConfig, S3Transfer
path = "/temp/"
fileName = "bigFile.gz" # this happens to be a 5.9 Gig file
client = boto3.client('s3', region)
config = TransferConfig(
    multipart_threshold=4*1024, # number of bytes
    max_concurrency=10,
    num_download_attempts=10,
)
transfer = S3Transfer(client, config)
transfer.upload_file(path+fileName, 'bucket', 'key')

結果:s3で5.9ギガファイル。複数のパーツが含まれていないようです。

この例 が見つかりましたが、partが定義されていません。

import boto3

bucket = 'bucket'
path = "/temp/"
fileName = "bigFile.gz"
key = 'key'

s3 = boto3.client('s3')

# Initiate the multipart upload and send the part(s)
mpu = s3.create_multipart_upload(Bucket=bucket, Key=key)
with open(path+fileName,'rb') as data:
    part1 = s3.upload_part(Bucket=bucket
                           , Key=key
                           , PartNumber=1
                           , UploadId=mpu['UploadId']
                           , Body=data)

# Next, we need to gather information about each part to complete
# the upload. Needed are the part number and ETag.
part_info = {
    'Parts': [
        {
            'PartNumber': 1,
            'ETag': part['ETag']
        }
    ]
}

# Now the upload works!
s3.complete_multipart_upload(Bucket=bucket
                             , Key=key
                             , UploadId=mpu['UploadId']
                             , MultipartUpload=part_info)

質問:boto3でマルチパートアップロードを使用する方法を知っている人はいますか?

7
blehman

この目的には boto3.s3.transfer を使用することをお勧めします。次に例を示します。

import boto3


def upload_file(filename):
    session = boto3.Session()
    s3_client = session.client("s3")

    try:
        print("Uploading file: {}".format(filename))

        tc = boto3.s3.transfer.TransferConfig()
        t = boto3.s3.transfer.S3Transfer(client=s3_client, config=tc)

        t.upload_file(filename, "my-bucket-name", "name-in-s3.dat")

    except Exception as e:
        print("Error uploading: {}".format(e))
7
deadcode

Boto3でコピーオプションだけを使用してみませんか?

s3.copy(CopySource={
        'Bucket': sourceBucket,
        'Key': sourceKey}, 
    Bucket=targetBucket,
    Key=targetKey,
    ExtraArgs={'ACL': 'bucket-owner-full-control'})

S3オブジェクトを初期化する方法の詳細と、明らかにここで利用可能な呼び出しの追加オプションがあります boto3 docs

2
Gourav Sengupta

あなたのコードはすでに正しかった。実際、マルチパートアップロードの最小限の例は次のようになります。

import boto3
s3 = boto3.client('s3')
s3.upload_file('my_big_local_file.txt', 'some_bucket', 'some_key')

マルチパートアップロードを明示的に要求したり、マルチパートアップロードに関連するboto3の低レベル関数を使用したりする必要はありません。 upload_fileを呼び出すだけで、ファイルサイズが特定のしきい値(デフォルトは8MB)を超えると、boto3は自動的にマルチパートアップロードを使用します。

S3の最終結果が複数の部分で構成されて表示されなかったという事実に混乱しているようです。

結果:s3で5.9ギガファイル。複数のパーツが含まれていないようです。

...しかし、これは期待される結果です。マルチパートアップロードAPIの要点は、複数のHTTPリクエストを介して単一のファイルをアップロードし、S3で単一のオブジェクトを作成できるようにすることです。

1
Mark Amery

コードスニペットでは、辞書で明らかにpart-> part1である必要があります。通常、複数のパートがあり(そうでない場合は、マルチパートアップロードを使用する理由)、'Parts'リストには各パートの要素が含まれます。

S3を処理するための新しいPythonicインターフェースにも興味があるかもしれません: http://s3fs.readthedocs.org/en/latest/

0
mdurant

パーツをパーツ1に変更

import boto3

bucket = 'bucket'
path = "/temp/"
fileName = "bigFile.gz"
key = 'key'

s3 = boto3.client('s3')

# Initiate the multipart upload and send the part(s)
mpu = s3.create_multipart_upload(Bucket=bucket, Key=key)
with open(path+fileName,'rb') as data:
    part1 = s3.upload_part(Bucket=bucket
                       , Key=key
                       , PartNumber=1
                       , UploadId=mpu['UploadId']
                       , Body=data)

# Next, we need to gather information about each part to complete
# the upload. Needed are the part number and ETag.
part_info = {
  'Parts': [
    {
        'PartNumber': 1,
        'ETag': part1['ETag']
    }
   ]
  }

# Now the upload works!
s3.complete_multipart_upload(Bucket=bucket
                         , Key=key
                         , UploadId=mpu['UploadId']
                         , MultipartUpload=part_info)
0
sarath kumar