Ich habe ein Skript zusammengestellt, das Daten in S3 hochlädt. Wenn die Datei weniger als 5 MB groß ist, wird sie als ein Chunk hochgeladen, aber wenn die Datei größer ist, führt sie einen mehrteiligen Upload durch. Ich weiß, dass die Schwellenwerte derzeit klein sind. Ich teste das Skript einfach in der Zwischenzeit. Wenn ich das Skript von Python aus starte, indem ich jede Funktion importiere und sie so laufe, funktioniert alles wie beabsichtigt. Ich bin mir bewusst, dass der Code gereinigt werden muss, da er noch nicht vollständig ist. Allerdings, wenn ich das Skript von der Kommandozeile ausgeführt Ich bin mit diesem Fehler begrüßt:Unterschiedliche Ergebnisse beim Ausführen eines Uploader-Skripts
Traceback (most recent call last):
File "upload_files_to_s3.py", line 106, in <module>
main()
File "upload_files_to_s3.py", line 103, in main
check_if_mp_needed(conn, input_file, mb, bucket_name, sub_directory)
File "upload_files_to_s3.py", line 71, in check_if_mp_needed
multipart_upload(conn, input_file, mb, bucket_name, sub_directory)
File "upload_files_to_s3.py", line 65, in multipart_upload
mp.complete_upload()
File "/usr/local/lib/python2.7/site-packages/boto/s3/multipart.py", line 304, in complete_upload
self.id, xml)
File "/usr/local/lib/python2.7/site-packages/boto/s3/bucket.py", line 1571, in complete_multipart_upload
response.status, response.reason, body)
boto.exception.S3ResponseError: S3ResponseError: 400 Bad Request
>The XML you provided was not well-formed or did not validate against our published schema
Hier ist der Code:
import sys
import boto
from boto.s3.key import Key
import os
import math
from filechunkio import FileChunkIO
KEY = os.environ['AWS_ACCESS_KEY_ID']
SECRET = os.environ['AWS_SECRET_ACCESS_KEY']
def start_connection():
key = KEY
secret = SECRET
return boto.connect_s3(key, secret)
def get_bucket_key(conn, bucket_name):
bucket = conn.get_bucket(bucket_name)
k = Key(bucket)
return k
def get_key_name(sub_directory, input_file):
full_key_name = os.path.join(sub_directory, os.path.basename(input_file))
return full_key_name
def get_file_info(input_file):
source_size = os.stat(input_file).st_size
return source_size
def multipart_request(conn, input_file, bucket_name, sub_directory):
bucket = conn.get_bucket(bucket_name)
mp = bucket.initiate_multipart_upload(get_key_name(sub_directory, input_file))
return mp
def get_chunk_size(mb):
chunk_size = mb * 1048576
return chunk_size
def get_chunk_count(input_file, mb):
chunk_count = int(math.ceil(get_file_info(input_file)/float(get_chunk_size(mb))))
return chunk_count
def regular_upload(conn, input_file, bucket_name, sub_directory):
k = get_bucket_key(conn, bucket_name)
k.key = get_key_name(sub_directory, input_file)
k.set_contents_from_filename(input_file)
def multipart_upload(conn, input_file, mb, bucket_name, sub_directory):
chunk_size = get_chunk_size(mb)
chunks = get_chunk_count(input_file, mb)
source_size = get_file_info(input_file)
mp = multipart_request(conn, input_file, bucket_name, sub_directory)
for i in range(chunks):
offset = chunk_size * i
b = min(chunk_size, source_size - offset)
with FileChunkIO(input_file, 'r', offset = offset, bytes = b) as fp:
mp.upload_part_from_file(fp, part_num = i + 1)
mp.complete_upload()
def check_if_mp_needed(conn, input_file, mb, bucket_name, sub_directory):
if get_file_info(input_file) <= 5242880:
regular_upload(conn, input_file, bucket_name, sub_directory)
else:
multipart_upload(conn, input_file, mb, bucket_name, sub_directory)
def main():
input_file = sys.argv[1]
mb = sys.argv[2]
bucket_name = sys.argv[3]
sub_directory = sys.argv[4]
conn = start_connection()
check_if_mp_needed(conn, input_file, mb, bucket_name, sub_directory)
if __name__ == '__main__':
main()
Dank!
Höchstwahrscheinlich verwenden Sie eine andere Umgebung in der Befehlszeile als die, in der Sie alles von Hand importieren. Was benutzt du in beiden Fällen? –
Ich führe das Skript von einem 'virtualenv' in IPython. Die Befehlszeile wird nur durch 'virtualenv' ausgeführt –
OK - so ist es nicht unmöglich, dass es eine Nichtübereinstimmung gibt. Können Sie 'boto .__ version__' in beiden Fällen überprüfen? –