Python3.7云函数写入Excel到GCS报FileNotFoundError如何解决?
云函数pandas写入Excel到GCS报错解决方案
报错根因
pandas的to_csv方法原生适配了gcsfs文件系统,可直接识别gs://前缀的GCS路径完成写入;但to_excel依赖的XlsxWriter/openpyxl引擎底层调用的是Python标准库的本地文件操作接口,无法直接识别GCS对象存储路径,因此会抛出路径不存在的错误。
解决方案
方案1:先写入临时目录再上传GCS
云函数运行环境预留了/tmp临时目录(最大支持512MB存储空间),先将Excel文件写入本地临时目录,再调用GCS SDK上传到目标存储桶即可。
修改后代码:
import xlsxwriter import openpyxl import numpy as np import pandas as pd from pandas.io import gbq from google.cloud import storage # 初始化GCS客户端 storage_client = storage.Client() # GCS配置参数 output_bucket = "samples" output_path_prefix = "results/output/" def testing(request): # 构造测试DataFrame data = [['tom', 10], ['nick', 15], ['juli', 14]] df = pd.DataFrame(data, columns = ['Name', 'Age']) # CSV可直接写入GCS df.to_csv(f"gs://{output_bucket}/{output_path_prefix}test_csv.csv", index=False) # Excel先写入本地临时目录 tmp_excel_path = "/tmp/test_excel.xlsx" df.to_excel(tmp_excel_path, index=False) # 上传到GCS对应路径 bucket = storage_client.bucket(output_bucket) blob = bucket.blob(f"{output_path_prefix}test_excel.xlsx") blob.upload_from_filename(tmp_excel_path) return "文件写入完成"
方案2:内存缓冲区写入(无本地磁盘IO)
如果Excel文件体积不大,可直接写入内存缓冲区,不需要操作本地磁盘,性能更高。
修改后代码:
import io import xlsxwriter import openpyxl import numpy as np import pandas as pd from pandas.io import gbq from google.cloud import storage # 初始化GCS客户端 storage_client = storage.Client() # GCS配置参数 output_bucket = "samples" output_path_prefix = "results/output/" def testing(request): # 构造测试DataFrame data = [['tom', 10], ['nick', 15], ['juli', 14]] df = pd.DataFrame(data, columns = ['Name', 'Age']) # CSV可直接写入GCS df.to_csv(f"gs://{output_bucket}/{output_path_prefix}test_csv.csv", index=False) # 将Excel写入内存缓冲区 output_buffer = io.BytesIO() with pd.ExcelWriter(output_buffer, engine='xlsxwriter') as writer: df.to_excel(writer, index=False) excel_content = output_buffer.getvalue() # 直接从内存上传到GCS bucket = storage_client.bucket(output_bucket) blob = bucket.blob(f"{output_path_prefix}test_excel.xlsx") blob.upload_from_string( excel_content, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) return "文件写入完成"
注意事项
- 云函数对应的服务账号需要授予目标GCS桶的
storage.objects.create权限,否则会触发权限报错 - 如果生成的Excel文件超过512MB,不要使用临时目录方案,建议拆分文件或者改用流式写入逻辑
内容的提问来源于stack exchange,提问作者James Lin
相关产品推荐
相关产品推荐

