You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Flask上传文件至Google Drive时遇类型错误求助

Flask上传文件到Google Drive报错TypeError的解决方法

问题概述

命令行脚本可正常将文件上传至Google Drive,但通过Flask HTML表单上传时触发错误:

TypeError: expected str, bytes or os.PathLike object, not BufferedReader

报错原因

  1. 参数类型不匹配:PyDrive的SetContentFile()方法要求接收文件路径字符串作为参数,代码中错误传递了open(path, "rb")返回的BufferedReader文件对象,导致类型校验失败。
  2. 变量引用错误:创建gfile时误用self.folderId,但folderId是视图函数的局部变量,不存在self上下文,会触发NameError。

修复步骤

1. 修正SetContentFile参数

将传递文件对象改为直接传递文件路径字符串:

# 错误写法
gfile.SetContentFile(open(path, "rb"))
# 正确写法
gfile.SetContentFile(path)

2. 修复变量引用错误

将self.folderId改为局部变量folderId:

# 错误写法
gfile = drive.CreateFile({'title': 'output.png', 'parents': [{'id': self.folderId}]})
# 正确写法
gfile = drive.CreateFile({'title': filename, 'parents': [{'id': folderId}]})

3. 可选优化:跳过本地文件保存

无需将上传文件保存到服务器本地,直接使用文件流上传,节省磁盘空间:

file = form.file.data
filename = secure_filename(file.filename)
gfile = drive.CreateFile({'title': filename, 'parents': [{'id': folderId}]})
gfile.content = file.stream  # 直接使用上传的文件流
gfile.Upload()

完整修正后的main.py代码

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
from werkzeug.utils import secure_filename
import os
from wtforms.validators import InputRequired
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'static/files'
app.config['SECRET_KEY'] = 'your-secret-key-here'  # 必须配置,用于Flask-WTF表单验证

class UploadFileForm(FlaskForm):
    file = FileField("File", validators=[InputRequired()])
    submit = SubmitField("Upload File")

@app.route('/', methods=['GET', "POST"])
@app.route('/home', methods=['GET', "POST"])
def home():
    form = UploadFileForm()
    gauth = GoogleAuth()
    drive = GoogleDrive(gauth)
    folderId = 'your-folder-id'  # 替换为实际的Google Drive文件夹ID
    # 自动创建上传目录(若使用本地保存方案)
    os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
    
    if form.validate_on_submit():
        file = form.file.data
        filename = secure_filename(file.filename)
        
        # 方案1:保存到本地后上传
        # save_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), app.config['UPLOAD_FOLDER'], filename)
        # file.save(save_path)
        # gfile = drive.CreateFile({'title': filename, 'parents': [{'id': folderId}]})
        # gfile.SetContentFile(save_path)
        
        # 方案2:直接用文件流上传(推荐)
        gfile = drive.CreateFile({'title': filename, 'parents': [{'id': folderId}]})
        gfile.content = file.stream
        
        gfile.Upload()
        return '文件已成功上传至Google Drive!'
    return render_template('index.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)

额外注意事项

  • 必须配置SECRET_KEY,否则Flask-WTF的CSRF验证会失败。
  • 替换代码中的your-folder-id为实际的Google Drive目标文件夹ID。
  • 若使用本地保存方案,os.makedirs代码会自动创建缺失的上传目录。

内容的提问来源于stack exchange,提问作者emb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:27:09