BytesIO文件无法上传Bitbucket及函数递归死循环问题修复
问题解决方案
问题根源拆解
- 无限递归循环:prod环境下,
gbl_delta_historization_api调用upload时传入的belle_type仍是"gbl_delta_business",导致upload反复触发递归分支,形成无限循环。 - BytesIO上传失败:生成的
BytesIO写入数据后指针停在末尾,未重置的话上传内容为空;同时递归分支中file.read()会消耗文件流内容,后续处理无有效数据。
具体修复步骤
1. 终止无限递归循环
修改gbl_delta_historization_api中调用upload的belle_type,让prod环境的处理后文件避开递归分支:
def gbl_delta_historization_api( git_login, git_write_token, file, upload, enviro='uat', belle_type='gbl_delta_business', belle_git_project='DQM', belle_git_repo='dqm-belle-repo', belle_git_branch='master' ): # ... 原有文件计算、拼接代码 ... df_real_out_buffer = BytesIO() df_real_out.to_csv(df_real_out_buffer, sep=";", index=False) # 重置BytesIO指针到起始位置,确保读取完整内容 df_real_out_buffer.seek(0) # 给prod环境设置专属belle_type,避免触发递归 target_belle_type = "gbl_delta_prod_processed" if enviro == "prod" else "gbl_delta_uat_business" return upload( belle_type=target_belle_type, environment=enviro, user=git_login, token=git_write_token, project=belle_git_project, repo=belle_git_repo, branch=belle_git_branch, file=df_real_out_buffer, filename="auto", overwrite=False ) # ... 原有else分支代码 ...
2. 修复BytesIO上传内容为空问题
调整upload函数,统一处理文件指针重置,同时优化递归分支的文件传递逻辑:
def upload( self, belle_type: str, environment: str, user: str, token: str, project: str, repo: str, branch: str, file, filename="auto", overwrite=False ) -> str: # 仅对原始待处理文件触发递归逻辑 if belle_type == "gbl_delta_business": file.seek(0) file_content = file.read() return gbl_delta_historization_api( git_login=user, git_write_token=token, file=file_content, upload=self.upload, enviro=environment, belle_type=belle_type, belle_git_project=project, belle_git_repo=repo, belle_git_branch=branch ) # 执行上传前强制重置指针,兼容所有文件流类型 file.seek(0) # ... 原有上传逻辑(获取res) ... return fn if res.status_code in [200, 409] else ""
3. 额外优化建议
- 把递归逻辑改为循环调用,避免递归深度过大引发栈溢出;
- 给
file参数增加类型校验(如判断是否为BytesIO或文件对象),提升代码健壮性; - 添加日志记录,跟踪每次函数调用的参数和执行状态,方便后续排查问题。
内容的提问来源于stack exchange,提问作者Samira
相关产品推荐
相关产品推荐

