You need to enable JavaScript to run this app. 在Google Cloud Functions中使用python-docx的文件读写与存储报错求助
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.05 20:15:02