Flask不本地存储文件直接从请求上传GCS报错如何解决
错误原因
你当前的upload_to_bucket方法使用的blob.upload_from_filename()接口要求入参为本地文件系统的路径字符串,但request.files['file']拿到的是Flask封装的FileStorage类实例,不属于本地路径字符串,因此触发属性错误。
你尝试传入file.value、file.file都无法解决的核心原因是没有更换适配类文件对象的GCS上传接口。
解决方案
GCS提供了blob.upload_from_file()接口,可以直接接收实现了read()方法的类文件对象,无需将文件落地到本地磁盘,刚好适配Flask的FileStorage实例,修改步骤如下:
1. 重写GCS上传方法
def upload_to_bucket(blob_name, file_obj, content_type=None): """ 直接从文件对象上传数据到GCS存储桶 """ storage_client = storage.Client() bucket = storage_client.get_bucket(bucket_name) blob = bucket.blob(blob_name) # 替换为upload_from_file接口,直接读取文件对象内容 blob.upload_from_file( file_obj, content_type=content_type ) # 返回公开访问URL return blob.public_url
2. 调整调用逻辑
注意FileStorage实例的filename属性才是用户上传的原文件名,name属性是表单中文件字段的名称,不要混淆:
# 从请求中获取文件对象 file = request.files['file'] # 传入文件对象、原文件名与文件MIME类型,保证GCS识别文件格式正确 url = upload_to_bucket(file.filename, file, content_type=file.content_type)
注意事项
- 确保服务已配置GCS身份认证,比如本地开发时配置
GOOGLE_APPLICATION_CREDENTIALS环境变量指向服务账号密钥文件,生产云环境绑定具有GCS写入权限的服务账号即可。 - 如果需要上传超过100M的大文件,可以额外开启GCS的分块上传配置,优化传输稳定性。
内容的提问来源于stack exchange,提问作者aakash singh
相关产品推荐
相关产品推荐

