如何通过Python替换Google Drive现有表格文件并保留文件ID?
问题场景与报错
我在Google Drive中有一份电子表格,需要每周替换内容,但不能更改文件ID(因为Google Data Studio中关联了对应图表)。我可以创建新表格,但无法替换现有文件的内容:
- 使用代码时出现「文件未找到」错误
- 添加文件夹ID后又出现「父级不可直接写入」错误
用户提供的代码:
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/drive.file'] store = file.Storage(c_path+'g_credentials_drive.json') g_creds = store.get() if not g_creds or g_creds.invalid: flow = client.flow_from_clientsecrets('client_secret.json', SCOPES) g_creds = tools.run_flow(flow, store) service = build('drive', 'v3', http=g_creds.authorize(Http())) Folder_id = '***' fileId = '***' para = {'name': 'file'} media = MediaFileUpload('C:/autorun/path/file.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', resumable=True, chunksize=1048576) files = service.files().update(fileId=fileId,body=para,media_body=media).execute() r = requests.patch("https://www.googleapis.com/upload/drive/v3/files/" + fileId + "?uploadType=multipart", headers=headers, files=files, )
问题分析与解决方案
1. 权限范围不足
原代码中的drive.metadata.readonly是只读权限,无法修改文件;drive.file仅允许操作当前应用创建的文件,如果目标表格不是该应用创建的,就会出现权限不足导致的「文件未找到」错误。需要调整权限范围:
SCOPES = ['https://www.googleapis.com/auth/drive'] # 全权限,或按需使用更细粒度的权限如drive.appdata(若文件在应用文件夹)
2. 冗余的API调用
代码中同时调用了Drive SDK的files().update()和手动发送requests.patch,这是重复操作,前者已经完成文件内容替换,后者完全多余,会导致错误。直接删除requests.patch部分即可。
3. 不必要的文件夹ID参数
更新文件内容时不需要指定文件夹ID,原代码中的Folder_id变量未被使用,但如果误将其加入update参数,会触发「父级不可直接写入」错误。确保update调用中不包含文件夹相关的参数。
4. 文件ID验证
确认fileId完全正确,且当前授权的Google账号对该文件拥有编辑权限(如果是共享文件,需确保账号被授予编辑权限)。
修正后的代码
from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload from oauth2client.file import Storage from oauth2client.client import flow_from_clientsecrets from oauth2client import tools import httplib2 # 调整权限范围 SCOPES = ['https://www.googleapis.com/auth/drive'] c_path = "你的凭证路径/" # 替换为实际路径 store = Storage(c_path + 'g_credentials_drive.json') g_creds = store.get() if not g_creds or g_creds.invalid: flow = flow_from_clientsecrets('client_secret.json', SCOPES) g_creds = tools.run_flow(flow, store) service = build('drive', 'v3', http=g_creds.authorize(httplib2.Http())) fileId = '你的目标文件ID' # 替换为实际文件ID # 仅保留需要更新的属性,这里保留文件名(可选,若不需要改文件名可删除body参数) para = {'name': 'file'} # 本地文件路径与MIME类型 media = MediaFileUpload( 'C:/autorun/path/file.xlsx', mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', resumable=True, chunksize=1048576 ) # 执行文件内容更新 updated_file = service.files().update( fileId=fileId, body=para, media_body=media ).execute() print(f"文件更新完成,文件ID: {updated_file['id']}")
内容的提问来源于stack exchange,提问作者santanicopandimonium
相关产品推荐
相关产品推荐

