使用Python调用Google Sheets API时出现数据失控插入异常
Google Sheets API未执行代码却失控重复插入数据的异常排查
问题描述
使用Python调用Google Sheets API时出现罕见异常:首次执行update或append方法插入数据成功且无报错后,仅修改range参数但未运行新代码,服务账户就开始向表格中失控插入多组不同的随机数据(数据维度与原数据一致,因测试用DataFrame为随机生成,每次插入值都不同)。
首次执行代码成功更新A2:D7,修改range为G10后未运行代码,表格A-D列开始失控插入数据,直至2148行。Cloud Console显示24小时内Google Sheets API调用量达3853次,仅约100次为手动触发,确认无其他用户访问凭据或项目。
测试代码
import datetime import pandas as pd import numpy as np from google.oauth2 import service_account from googleapiclient.discovery import build # build a resource from json credentials service_acct_credentials = 'path_to_credentials.json' credentials = service_account.Credentials.from_service_account_file(filename=service_acct_credentials) service = build('sheets', 'v4', credentials=credentials) # create a 5x3 dataframe with random int values df_rand = pd.DataFrame(np.random.randint(100, size=(5, 3)), columns=['A', 'B', 'C']) # generate a list of 5 dates between today and 1 year ago today one_year_ago = datetime.date.today() - datetime.timedelta(days=365) dates = [one_year_ago + datetime.timedelta(days = np.random.randint(1, 365)) for _ in range (5)] # turn list of dates into a 5x1 dataframe df_date = pd.DataFrame(dates, columns=['D'], dtype=str) # join both dfs into a 5x4 dataframe df = df_rand.join(df_date, how='left').reset_index(drop=True) # convert dataframe to a list of dataframe rows, casted to strings, including the column names values = df.T.reset_index().T.to_numpy(dtype=str).tolist() service.spreadsheets().values().update( spreadsheetId='1obMvYaote-agFUuDv1bQVYcRr9KqkrdecPh3ErTykWQ', valueInputOption='RAW', range='{}!{}'.format('sheet2', 'A2'), body=dict(major_dimension='ROWS', values=values) ).execute()
已尝试的无效方案
- 将update方法赋值给request变量,未执行execute仍自动插入数据;
- 调用
service.close()无法终止异常; - 重启编辑器后异常暂时停止,但再次执行请求后复发;
- 更换同文档内工作表、更换文档、更换机器和虚拟环境。
排查与解决建议
立即更换服务账户凭据
登录Google Cloud Console,找到对应项目的服务账户,删除当前的JSON密钥并重新生成新的凭据文件。当前凭据可能已被绑定到某个后台自动执行的进程,更换凭据可直接切断异常调用的权限。检查IDE的自动执行机制
- 确认是否开启了代码自动运行功能(如Jupyter的自动重载、VS Code/PyCharm的保存后自动执行脚本),这类功能可能在修改代码后自动触发执行,无需手动点击运行。
- 打开系统任务管理器,杀死所有残留的Python进程,避免旧进程在后台持续发起API调用。
排查代码中的隐式执行逻辑
- 检查代码是否存在意外的循环逻辑(如未加终止条件的
while循环),或函数被装饰器/框架意外重复调用。 - 确认
values生成逻辑是否触发了隐式计算,某些数据处理库的懒加载机制可能会在不经意间执行代码块。
- 检查代码是否存在意外的循环逻辑(如未加终止条件的
添加调用日志定位触发源
在API调用代码前后添加时间戳日志,对比本地日志与Cloud Console的API调用记录,确认异常调用是否来自本地进程:import logging from datetime import datetime logging.basicConfig(level=logging.INFO) range_value = '{}!{}'.format('sheet2', 'A2') logging.info(f"[{datetime.now()}] 手动发起API调用,range={range_value}") service.spreadsheets().values().update( spreadsheetId='1obMvYaote-agFUuDv1bQVYcRr9KqkrdecPh3ErTykWQ', valueInputOption='RAW', range=range_value, body=dict(major_dimension='ROWS', values=values) ).execute()临时限制API调用配额
在Google Cloud Console的Sheets API设置中,调低服务账户的调用配额(如设置为每分钟10次),限制异常调用的频率,同时便于观察触发规律。
内容的提问来源于stack exchange,提问作者soph.py
相关产品推荐
相关产品推荐

