基于Google API与Python:避免获取Drive中未存在文件的ID
修复Google Drive CSV同步脚本的新增文件处理问题
问题根源
原脚本中getSpreadsheetId函数在检测到Drive中无对应文件时,上传新文件后直接调用exit()终止程序,导致:
- 函数无返回值,主循环中
oldSpreadsheetId变量赋值失败 - 后续删除、重新创建表格的逻辑无法执行,引发内核崩溃
- 脚本终止后无法处理剩余文件
修改后的完整脚本
import gspread import os from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload gc = gspread.oauth(credentials_filename='/users/krzysztofpaszta/credentials.json') service = build("drive", "v3", credentials=gc.auth) folder_id = '19vrbvaeDqWcxFGwPV82APWYTmBMEn-hi' def getSpreadsheetId(filename, filePath): # 使用f-string简化查询语句拼接 q = f"name='{filename}' and mimeType='application/vnd.google-apps.spreadsheet' and trashed=false" res = service.files().list(q=q, fields="files(id)", corpora="allDrives", includeItemsFromAllDrives=True, supportsAllDrives=True).execute() items = res.get("files", []) if not items: print(f"No existing spreadsheet found for '{filename}', uploading new file.") file_metadata = { "name": filename, "parents": [folder_id], "mimeType": "application/vnd.google-apps.spreadsheet", } media = MediaFileUpload(f"{filePath}/{filename}.csv") file = service.files().create(body=file_metadata, media_body=media, fields="id", supportsAllDrives=True).execute() file_id = file.get("id") print(f"New spreadsheet uploaded, ID: {file_id}") # 返回新文件ID和"是否为新增文件"的标记 return file_id, False # 返回已有文件ID和"文件已存在"的标记 return items[0]["id"], True filePath = '/users/krzysztofpaszta/CSVtoGD' os.chdir(filePath) files = os.listdir() for filename in files: fname_parts = filename.split(".") # 跳过非CSV文件,避免文件名无后缀导致索引错误 if len(fname_parts) != 2 or fname_parts[1].lower() != "csv": continue base_name = fname_parts[0] old_spreadsheet_id, file_exists = getSpreadsheetId(base_name, filePath) # 仅当文件已存在时执行删除操作 if file_exists: gc.del_spreadsheet(old_spreadsheet_id) print(f"Deleted old spreadsheet: {old_spreadsheet_id}") # 创建新表格并导入CSV内容 sh = gc.create(base_name, folder_id) # 使用with语句安全打开文件,指定UTF-8编码避免乱码 with open(filename, "r", encoding="utf-8") as f: content = f.read().encode("utf-8") gc.import_csv(sh.id, content) print(f"Successfully updated spreadsheet for '{filename}', new ID: {sh.id}")
关键修改点
移除
exit()并返回状态标记:getSpreadsheetId函数不再终止程序,而是返回文件ID和一个布尔值(标记文件是否已存在)- 主循环根据标记判断是否需要执行删除旧文件的操作
增强鲁棒性:
- 用f-string替代字符串拼接,避免语法错误和注入风险
- 增加非CSV文件的判断逻辑,防止文件名无后缀时出现索引错误
- 使用
with语句安全管理文件句柄,指定UTF-8编码处理中文等特殊字符
优化逻辑流程:
- 无论文件是否存在,统一执行"创建新表格+导入CSV"的流程,保证数据一致性
- 仅在文件已存在时删除旧表格,避免对新增文件执行无效删除操作
内容的提问来源于stack exchange,提问作者Kamilminiprogramer
相关产品推荐
相关产品推荐

