Google Drive API文件上传失败求助:智能考勤系统训练文件存储问题
问题描述
首次开发大型项目(课堂智能考勤系统),通过Python人脸检测代码训练图像集生成人脸训练文件,由于不建议将大文件存入数据库,尝试使用Google Drive API上传该文件。遇到两个问题:
- 测试代码执行显示成功,但Google Drive中找不到上传的文件
- 若在
file_metadata中添加parents字段指定目标文件夹,代码直接失效
测试代码如下:
from __future__ import print_function import os from google.oauth2 import service_account from googleapiclient.discovery import build from httplib2 import Http from googleapiclient.http import MediaFileUpload SCOPES = ['https://www.googleapis.com/auth/drive.file'] SERVICE_ACCOUNT_FILE = 'C:\Users\danie\OneDrive\Documentos\PAP\teste drive\iris-face-models-565de449aa27.json' credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES ) drive_service = build('drive', 'v3', credentials=credentials) target_folder_id = '1MAM4CPDMbqpzP5rZb1Zw0A15r4U7B4Kv' file_metadata = { 'name': 'test_file.txt', #'parents': [target_folder_id] 添加该行后代码失效 } media = MediaFileUpload('C:\Users\danie\OneDrive\Documentos\PAP\testeicheiro\Ficheiro_teste.txt', mimetype='text/plain') file = drive_service.files().create(body=file_metadata, media_body=media, fields='id').execute()
问题分析
这两个问题的核心原因是服务账号(Service Account)的Drive空间和个人Google Drive空间完全独立:
- 代码执行成功但看不到文件:文件实际被上传到了服务账号自身的Drive存储空间,而非你的个人Drive,所以在个人Drive中无法找到
- 添加
parents字段失效:你指定的文件夹ID属于个人Drive,服务账号默认没有访问权限,因此上传时会因权限不足报错
解决步骤
1. 给服务账号分配个人Drive文件夹权限
- 打开个人Google Drive,找到目标文件夹(对应代码中的
target_folder_id) - 右键点击文件夹 → 「共享」
- 输入服务账号的邮箱(可在
SERVICE_ACCOUNT_FILE对应的JSON文件中找到client_email字段的值) - 给服务账号分配「编辑」权限,保存设置
2. 修正Windows路径转义问题
Windows路径中的反斜杠\需要转义为\\,否则可能导致文件读取失败:
# 修正服务账号文件路径 SERVICE_ACCOUNT_FILE = 'C:\\Users\\danie\\OneDrive\\Documentos\\PAP\\teste drive\\iris-face-models-565de449aa27.json' # 修正待上传文件路径 media = MediaFileUpload('C:\\Users\\danie\\OneDrive\\Documentos\\PAP\\testeicheiro\\Ficheiro_teste.txt', mimetype='text/plain')
3. 恢复parents字段并添加错误捕获
在代码中启用parents字段,同时添加异常捕获便于排查问题:
target_folder_id = '1MAM4CPDMbqpzP5rZb1Zw0A15r4U7B4Kv' file_metadata = { 'name': 'test_file.txt', 'parents': [target_folder_id] } try: file = drive_service.files().create(body=file_metadata, media_body=media, fields='id').execute() print(f"文件上传成功,ID: {file.get('id')}") except Exception as e: print(f"上传失败: {str(e)}")
4. 验证服务账号的文件(可选)
如果需要查看服务账号Drive中的文件,可以调用files().list()接口列出所有文件:
results = drive_service.files().list(pageSize=10, fields="nextPageToken, files(id, name)").execute() items = results.get('files', []) if not items: print('没有找到文件。') else: print('文件列表:') for item in items: print(f"{item['name']} ({item['id']})")
替代方案
如果觉得Google Drive API配置繁琐,可考虑以下方案:
- 国内对象存储服务:如阿里云OSS、腾讯云COS,配置简单,支持大文件分片上传,适合存储训练文件这类大资源
- 本地文件服务器:若项目部署在局域网内,用Nginx或FastAPI搭建简易文件存储服务,文件直接存在服务器磁盘,数据库仅存储文件路径
- Dropbox API:权限配置逻辑更直观,适合个人或小型团队项目
内容的提问来源于stack exchange,提问作者Daniel Barreto
相关产品推荐
相关产品推荐

