【问题标题】:Downloading AWS S3 file with python boto returns 404 even though file exists即使文件存在,使用 python boto 下载 AWS S3 文件也会返回 404
【发布时间】:2017-01-23 08:27:40
【问题描述】:

我正在使用 Python boto 模块来访问 AWS S3 文件。 我使用 UNLOAD 命令从 Redshift 卸载文件,文件会自动压缩。 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 会返回 404 错误,文件不存在。我已经手动检查了 S3 存储桶中的文件,并且它有数据。 我读过如果更改尚未传播,S3 可能会返回此类错误。这就是下载功能看起来像这样的原因。如果文件出现错误,我会尝试再次下载相同的文件。问题是我第二次下载文件时,它是空的,我丢失了一些数据。 (十分之一)。

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

【问题讨论】:

  • 另一种选择是使用AWS Command-Line Interface (CLI) 使用aws s3 syncaws s3 cp --recursive 命令下载文件。
  • 我可以在下载功能中使用它,但您认为它可以解决 404 错误吗?我认为错误发生在 AWS 端,而不是 Python 端。

标签: python amazon-web-services amazon-s3 http-status-code-404 boto


【解决方案1】:

我设法通过改变下载功能的工作方式解决了这个问题。我从那里删除了 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,表示出现问题。之后,我有一个功能可以在引发系统错误并使整个过程失败之前再次尝试下载整个文件夹三次。

【讨论】:

    猜你喜欢
    • 2019-10-13
    • 2016-09-23
    • 2012-10-15
    • 1970-01-01
    • 2018-03-04
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    相关资源
    最近更新 更多