python - 将文件上传到某个驱动器时发生错误时,有没有办法实现重试功能?
问题描述
我正在从事一个项目,负责每天将文件从数据库上传到 OneDrive 中的驱动器。当您上传一半文件时,出于一个奇怪的原因,它会突然失败。我想知道是否有一种方法可以实现用python编写的“重试”函数,当文件上传过程失败时,它会执行并重试三次,如果在三次结束后失败并显示“上传过程”之类的消息今天失败了”。欢迎任何形式的帮助。Python版本**3.8.3
执行整个上传过程的代码如下
if __name__ == '__main__':
reg_manager = RegistryManager()
keys = reg_manager.get_keys()
try:
tables = BCPManager.load_tables()
dir_name = datetime.today().strftime('%Y-%m-%d')
dir_path = f'./files/{dir_name}'
final_file = 'tables.zip'
FileManager.create_folder(dir_path)
for table in tables:
table_columns = BCPManager.get_table_columns(table, dir_path)
table_data = BCPManager.get_table_data(table, dir_path, 3)
table_path = f'{dir_path}/{table}.csv'
FileManager.merge_table_files(table_path, table_columns, table_data)
dir_files = FileManager.get_directory_files(dir_path)
with ZipFile(
f'{dir_path}/{final_file}',
'w',
compression=ZIP_DEFLATED,
compresslevel=9
) as zip_file:
for dir_file in dir_files:
if dir_file.name == final_file:
continue
print(f'zipping file {dir_file.path}')
zip_file.write(dir_file.path, arcname=dir_file.name)
FileManager.remove_file(dir_file.path)
file_size = os.path.getsize(f'{dir_path}/{final_file}')
uploader = OneDriveUploader(
'drives/{DriveID}/items/{ChildreID}',
{
'client_id': keys['client_id'],
'client_secret': keys['client_secret']
}
)
uploader.create_folder(dir_name)
print('uploading file')
with open(f'{dir_path}/{final_file}', 'rb') as open_file:
print('getting file chunks')
chunks = FileManager.get_file_chunks(open_file)
index = 0
offset = 0
headers = dict()
upload_url = uploader.get_upload_link(dir_name, final_file)
for chunk in chunks:
offset = index + len(chunk)
headers['Content-Type'] = 'application/octet-stream'
headers['Content-Length'] = str(file_size)
headers['Content-Range'] = f'bytes {index}-{offset - 1}' \
f'/{file_size} '
uploader.upload_file_chunk(upload_url, chunk, headers)
index = offset
print('removing file')
FileManager.remove_file(f'{dir_path}/{final_file}')
except Exception as uploader_exception:
print('There was an error while uploading files')
print(uploader_exception)
message = Mail(
from_email='test@outlook.com',
to_emails=['test@gmail.com'],
subject='OneDrive upload failed',
html_content='Something went wrong while uploading files to '
'onedrive')
try:
sg = SendGridAPIClient(keys['sendgrid_api_key'])
response = sg.send(message)
print(response.status_code)
print(response.body)
print(response.headers)
except Exception as e:
print(e)
上传一半文件后,会引发以下错误:
<Response [202]> {'expirationDateTime': '2021-08-14T12:01:08.341Z', 'nextExpectedRanges': ['11141120-109593649']}
<Response [202]> {'expirationDateTime': '2021-08-14T12:01:08.341Z', 'nextExpectedRanges': ['11468800-109593649']}
<Response [202]> {'expirationDateTime': '2021-08-14T12:01:08.341Z', 'nextExpectedRanges': ['11796480-109593649']}
There was an error while uploading files
Expecting value: line 1 column 1 (char 0)
202
b''
Server: nginx
Date: Mon, 09 Aug 2021 12:01:33 GMT
Content-Length: 0
Connection: close
X-Message-Id: cMEuH6TtSHCmiKMKUzV1Dg
Access-Control-Allow-Origin: https://sendgrid.api-docs.io
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
Access-Control-Max-Age: 600
X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html
Strict-Transport-Security: max-age=600; includeSubDomains
对此有些好奇的是,它不会一周中的每一天都失败,它每周偶尔会失败一次,这就是为什么要实现一个负责重试文件上传的函数的想法,如果失败了 3 次尝试过,没有任何反应,因为还有 6 天。
解决方案
好吧,使用递归非常简单。这是我的实现:
def upload(runs):
try:
if runs != 0:
"UPLOAD FILES HERE"
except Exception as uploader_exception:
print("UPLOAD FAILED {} times, trying again".format(4-runs))
upload(runs-1)
upload(3)
推荐阅读
- r - 无法将一些 unicode 字符写入文件
- java - adb devices => 没有权限(plugdev 组中的用户;您的 udev 规则错了吗?)
- android - Xamarin Android 动画更改位置
- java - 使用服务作为“工厂”返回不同的 Bean 实现
- jenkins - qTest | Jenkinsfile 流水线集成
- android - 非英特尔 AVD 仿真器
- html - 在手机Bootstrap 4上查看时图像跳出div
- javascript - Angular 2将变量从一个组件传递到另一个组件
- node.js - 每次nodejs中的另一个请求失败时重试一个请求
- linux - 配置 SSL ACL 时 kafka 消费者无法连接到服务器:{test-topic=LEADER_NOT_AVAILABLE}