使用带 python 的 gspread 在单个电子表格中复制并更新多个工作表的最节省资源的方法是什么?

What is the most resource efficient way to duplicate and then update multiple worksheets in a single spreadsheet using gspread with python?

我正在编写一个 python 脚本(连同其他一些东西)在 google 工作表上复制模板电子表格,在该电子表格中复制一个选项卡(工作表)最多 25 次,并且然后使用脚本提供的一些信息更新那些重复的选项卡。到目前为止,我完成此操作的方法是执行以下操作:

copied_spreadsheet = 'my new spreadsheet'

client.copy('(spreadsheet key))', title=copied_spreadsheet, copy_permissions=True)
copied_spreadsheet = client.open(spreadsheet_name)

要复制模板电子表格,则:

for idx, tab_name in enumerate(list_of_tabs_to_add):
     copied_spreadsheet.worksheet('template_tab').duplicate(insert_sheet_index=idx + 1, new_sheet_name=tab_name)
     supplied_information = ['stuff to add to the duplicated tab']
     copied_spreadsheet.worksheet(tab_name).update('A1:F3', supplied_information, value_input_option='USER_ENTERED')

当我不得不将模板选项卡复制大约 20 次时,这非常有效,但是当我尝试复制 25 次时,我发现自己偶尔会 运行 陷入超出配额的资源错误每个用户每分钟的读取请求。错误看起来像这样:

gspread.exceptions.APIError: {'code': 429, 'message': "Quota exceeded for quota metric 'Read requests' and limit 'Read requests per minute per user' of service 'sheets.googleapis.com' for consumer (etc...)

我已经尝试过一些非常棘手的解决方案,比如在循环之间添加一个 time.sleep() 命令来尝试充当一种缓冲区,这样我就不会很快达到配额,这有点帮助,但结果可能会有点碰运气。

除了请求更高的配额外,我还能做些什么来提高我的代码效率吗?我相信我正在使用默认配额,而且我不认为我正在做的是那么密集,所以我的感觉是我没有尽可能高效地编写这个解决方案。

在我的脑海中,我觉得我可以从中获得最大效率的地方是复制和更新 25 次的循环。有什么方法可以将模板工作表存储到一个变量中,复制并修改该变量,然后使用一个命令而不是 25 次上传 25 个副本?我对数据帧或 gspread_dataframes 模块不是很熟悉,但是该库是否也存在潜在的解决方案,或者我目前正在做的事情是最好的方法,需要一个简单的配额增加?

我相信你的目标如下。

  • 你想在Google中复制一个sheet Spreadsheet 25次,并且想把supplied_information的值放到每个复制的sheet中.
    • 在这种情况下,您想减少脚本的处理成本。
  • 您想使用 python 的 gspread 来实现此目的。
  • 您已经能够使用表格 API.
  • 获取和放置 Spreadsheet 的值

在这种情况下,我想提出以下流程。

  1. 在复制的 Google Spreadsheet.
  2. 中检索 template_tab 的 sheet ID
  3. 为工作表 API.
  4. 创建 2 个“batchUpdate”和“values.batchUpdate”请求
  5. 使用 gspread 请求 batchUpdate 方法。
  6. 使用请求模块请求 values.batchUpdate 方法。
    • 因为在gspread中,在现阶段,values.batchUpdate这个方法是没有包含的。因此,我通过从 gspread 的授权脚本中检索访问令牌来使用请求模块来使用它。

在此流程中,使用了 3 个工作表配额 API。当这个流程反映到你的脚本中时,它变成如下。 顺便说一句,似乎 client.copy() returns 一个 Spreadsheet 实例。

修改后的脚本:

请设置'(spreadsheet key))'list_of_tabs_to_addsupplied_information

client = gspread.authorize(credentials) # Please use your "credentials" here.

copied_spreadsheet = 'my new spreadsheet'
copied_spreadsheet = client.copy('(spreadsheet key))', title=copied_spreadsheet, copy_permissions=True)

list_of_tabs_to_add = [###] # <--- Please set value here.

# 1. Retrieve the sheet ID of `template_tab` in the copied Google Spreadsheet.
srcSheetId = copied_spreadsheet.worksheet('template_tab').id

# 2. Create 2 requests for "batchUpdate" and "values.batchUpdate" for Sheets API.
requests1 = []
requests2 = []
for idx, tab_name in enumerate(list_of_tabs_to_add):
    temp = idx + 1
    requests1.append({"duplicateSheet": {"sourceSheetId": srcSheetId, "insertSheetIndex": temp, "newSheetName": tab_name}})

    supplied_information = [###] # <--- Please set value here.

    requests2.append({"range": tab_name, "values": supplied_information})

# 3. Request batchUpdate method using gspread.
res1 = copied_spreadsheet.batch_update({"requests": requests1})

# 4. Request values.batchUpdate method using requests module.
res2 = requests.post(
    'https://sheets.googleapis.com/v4/spreadsheets/' + copied_spreadsheet.id + '/values:batchUpdate',
    headers={"Authorization": "Bearer " + credentials.access_token, "Content-Type": "application/json"},
    data=json.dumps({"data": requests2, "valueInputOption": "USER_ENTERED"}),
)
  • 在此脚本中,需要包含 requestsjson 库。

参考文献: