Flask上传CSV至数据库时Google Cloud Shell报FileNotFoundError问题咨询
报错根因
- 你本地Cloud Shell开发时手动创建了
files目录,但打包部署到Cloud Run的容器镜像中没有预先创建该路径,运行时无法找到对应目录 - Google Cloud Run的容器文件系统默认仅
/tmp目录具备可写权限,其余目录均为只读状态,你定义的相对路径files/不在可写范围内,写入操作会直接失败 - 代码存在逻辑漏洞:文件格式校验不通过的else分支直接调用
os.remove(file_path),但此时还未执行f.save()操作,该路径本身就不存在,也会触发同类报错
临时适配方案(无需修改存储逻辑,适合单实例临时处理场景)
直接将上传路径改为Cloud Run允许的可写临时目录,同时应用启动时自动创建目标文件夹,修复逻辑漏洞即可,修改后代码参考:
import os from flask import Flask, request, render_template UPLOAD_FOLDER = '/tmp/files' app = Flask(__name__) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER # 启动时自动创建目录,不存在则创建,已存在也不会报错 os.makedirs(UPLOAD_FOLDER, exist_ok=True) # 你的allowed_file方法定义保持不变 def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() == 'csv' def parseCSV(file_path): # 你原有的CSV解析逻辑保持不变 pass @app.route('/upload', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': f = request.files['file'] file_path = os.path.join(app.config['UPLOAD_FOLDER'], f.filename) if f and allowed_file(f.filename): f.save(file_path) hasil = parseCSV(file_path) # 处理完成后可主动删除临时文件,避免占用/tmp空间 os.remove(file_path) return render_template("testes.html", data=hasil) else: # 校验不通过时文件并未保存,无需执行删除操作,直接返回即可 return render_template("testes.html", data="Oh no")
注意:该方案使用的/tmp目录为临时存储,Cloud Run实例重启、销毁或扩容时,存储的文件会全部丢失,且最大仅支持8GiB存储,仅适合文件处理完就删除的临时场景。
生产级方案(适合需要持久化存储、多实例部署场景)
Cloud Run本地文件系统不适合持久化存储文件,生产环境建议搭配Google Cloud Storage使用:
- 安装
google-cloud-storage依赖包 - 上传文件时直接将文件流写入GCS存储桶,无需写入本地文件系统
- 解析CSV时直接从GCS读取文件流即可,无需本地存储路径
内容的提问来源于stack exchange,提问作者Hikm Nasir
相关产品推荐
相关产品推荐

