在Google Cloud Functions中使用python-docx的文件读写与存储报错求助
问题根因与可运行方案
两类报错的核心原因
- 首次运行代码报
OSError: [Errno 30] Read-only file system:Google Cloud Functions的代码部署目录为只读挂载,仅/tmp临时目录具备写入权限,直接在代码所在目录保存docx文件必然触发权限错误。 - 修改后代码报
AttributeError: '_io.BytesIO' object has no attribute 'encode':- 类型误用:
io.BytesIO是承载二进制数据的内存流对象,本身不存在字符串的.encode()方法 - 逻辑错位:
bucket.blob()需要传入存储桶内的目标文件名字符串,不能将内存流对象作为参数传入当文件名 - 上传源错误:代码试图上传本地不存在的
document.docx文件,实际生成的文档已经存在内存流中,无需落盘再上传
- 类型误用:
修正后的可直接运行代码
from google.cloud import storage from docx import Document import io # 全局初始化存储客户端,降低冷启动开销 storage_client = storage.Client() OUTPUT_BUCKET = 'out_bucket' def test(request): # 初始化内存流,完全规避本地文件写入的权限限制 docx_stream = io.BytesIO() # 加载同部署包内的模板文档:只读目录下的文件可正常读取 document = Document('blank_doc.docx') # 此处可补充实际的文档编辑逻辑,如新增段落、表格等 # 将生成的docx直接写入内存流,不做本地磁盘落盘 document.save(docx_stream) # 重置流指针到起始位置,避免上传时读取到空内容 docx_stream.seek(0) # 上传文档到Cloud Storage bucket = storage_client.get_bucket(OUTPUT_BUCKET) # 定义存储桶内的目标文件路径 target_blob = bucket.blob('generated/test.docx') # 直接从内存流上传,指定docx对应的MIME类型 target_blob.upload_from_file( docx_stream, content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document' ) return "文档已生成并上传", 200
关键注意事项
- 模板文件
blank_doc.docx必须和函数入口文件main.py处于同一代码目录,随部署包一起上传,只读目录下的资源文件可被正常读取,不存在权限问题 - 若确实需要将文件临时落盘,必须将保存路径指定为
/tmp/xxx.docx,但函数实例销毁后/tmp内的文件会被自动清空,不适合作为长期存储路径 - 内存流操作必须在写入完成后调用
seek(0)重置指针,否则会因指针停留在流末尾,导致上传的文件为空
内容的提问来源于stack exchange,提问作者Hari
相关产品推荐
相关产品推荐

