0

Я использую модуль Python boto для доступа к файлам AWS S3. Я выгружаю файлы из Redshift с помощью UNLOAD команд и файлов автоматически gzipped. Redshift генерирует 10 частей одного файла.Загрузка файла AWS S3 с python boto возвращает 404, хотя файл существует

Это часть кода, который я использую, чтобы получить список файлов и вызовите функцию загрузки:

key_list = bucket.list('folder_on_the_bucket') 
pool = ThreadPool(processes=10) 
partial_download = partial(download,0) 
pool.map(partial_download, key_list) 

Это функция загрузки:

def download(retry_cnt,key): 
retry_cnt = retry_cnt 
key = key 
try: 
    #make sure that I download only files, not folders 
    if key.name[-1]=='/' or key.name[-1]=='\\': 
     pass 
    else: 
     log.info("Downloading %s" % local_dir+ntpath.basename(key.name)) 
     key.get_contents_to_filename(local_dir+ntpath.basename(key.name)) 
     if retry_cnt > 0: 
      #copy all files that needed to be retried to a specific directory (for debugging purposes) 
      shutil.copyfile(local_dir+ntpath.basename(key.name), 'error_files_folder'+ntpath.basename(key.name)) 
except: 
    if retry_cnt < 3: 
     retry_cnt += 1 
     log.warning("error downloading file %s, retrying for the %s. time" % (str(key.name),str(retry_cnt))) 
     log.warning(str(sys.exc_info()[1])) 
     time.sleep(5) 
     download(retry_cnt,key) 
    else: 
     log.error(sys.exc_info()[1]) 
     sys.exit("Unable to download file") 

Проблема в том, что иногда, AWS вернет ошибку 404, файл не существует. Я проверил вручную и файлы apperas в ведро S3, и у него есть данные. Я читал, что S3 может вернуть такую ​​ошибку, если изменения не были распространены. Вот почему функции загрузки выглядят так. Если с файлом произошла ошибка, я снова попытаюсь загрузить тот же файл. Проблема в том, что во второй раз, когда я загружаю файл, он пуст, и я теряю некоторые данные. (одна десятая его).

Эта проблема возникает случайным образом в разных ковшиках и папках.

+0

Другой вариант - использовать интерфейс командной строки [AWS] (http://aws.amazon.com/cli/) для загрузки файлов с помощью 'aws s3 sync' или' aws s3 cp - -рекурсивных' команд. –

+0

Я мог бы использовать это в функции загрузки, но считаете ли вы, что он может решить ошибку 404? Я понял, что ошибка происходит на стороне AWS, а не на Python. – quickshare

ответ

0

Мне удалось решить эту проблему, изменив способ работы функции загрузки. Я удалил попытку оттуда и установил ее вокруг части вызывающего ее кода.

def get_download_files(): 
    global key_list 
    key_list = bucket.list(s3_full_path) 
    for f in key_list: 
     log.info(f) 
    try: 
     pool = ThreadPool(processes=10) 
     pool.map(download, key_list) 
    except: 
     log.warning("error occured while downloading") 
     log.warning(sys.exc_info()[1]) 
     global error_cnt 
     error_cnt = 1 
     pass 

Используя эту функцию, можно убедиться, что если какой-либо из файлов не удается загрузить какой-либо причине, я установить error_cnt 1 о том, что там была проблема. После этого у меня есть функция, которая повторяет попытку загрузить всю папку снова три раза, прежде чем бросать системную ошибку и провалить весь процесс.