使用 python boto returns 404 下载 AWS S3 文件,即使文件存在

Downloading AWS S3 file with python boto returns 404 even though file exists

我正在使用 Python boto 模块访问 AWS S3 文件。 我使用 UNLOAD 命令从 Redshift 卸载文件,文件会自动 gzip 压缩。 Redshift 生成一个文件的 10 个部分。

这是我用来获取文件列表并调用下载函数的部分代码:

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 会return 404 错误,文件不存在。我已经手动检查了 S3 存储桶中的文件 apperas 并且它有数据。 我读过如果更改没有传播,S3 可能会出现 return 这样的错误。这就是下载功能看起来像这样的原因。如果文件出现错误,我会尝试再次下载相同的文件。问题是我第二次下载文件时,它是空的,我丢失了一些数据。 (十分之一)。

此问题随机发生在不同的存储桶和文件夹上。

我通过更改下载功能的工作方式设法解决了这个问题。我从那里删除了 try 并将其设置在调用它的代码部分周围。

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,表示出现问题。之后,我有一个功能可以在抛出系统错误和整个过程失败之前重试下载整个文件夹 3 次。