javascript - 未记录的 Sheet API 限制问题

标签 javascript google-apps-script google-sheets-api http-status-code-413

我已经看过有人遇到类似问题的帖子,但找不到明确的答案。

我尝试使用以下代码行检索包含 264735 个槽的二维数组:

  var optionalArguments = {majorDimension: "ROWS",
                     valueRenderOption: "FORMULA",
  };
  var sourceValuesObject = Sheets.Spreadsheets.Values.get(spreadsheetId, rangeA1Notation, optionalArguments)

但这是我得到的:

response code : 413. Message : response too large.

这看起来很奇怪,因为我看不到这种无处不在的限制以及如果 300000 个或更少的单元格会导致 API 错误,用户如何获取大量数据。

我已经尝试拆分请求并且它有效,但这使我的代码变得更加复杂和缓慢,而且在尝试将值更新回我的工作表范围时我得到了一个空响应。

我指向的方向是否正确,这是否正常,是否有解决方法?

编辑: Here is a sample spreasheet

首先,我尝试使用 Sheets.Spreadsheets.Values.get 获取拆分范围 在 for 循环中,它起作用了。

batchGet 做同样的事情会给我同样的错误,所以我想我的单元格中的数据太大了。

最佳答案

这个解决方法怎么样?

实验:

此实验使用您共享的示例电子表格。

当UrlFetchApp 直接调用Sheets API 端点时,如果响应大小大于50 MB (52,428,800 Byte),则返回小于50 MB 的响应。 50 MB 的大小是由于 UrlFetchApp 的限制。另一方面,在 Advanced Google Service 中,它无法确认这种情况,因为超过限制时会发生错误。所以通过使用UrlFetchApp,可以确认你的情况错误的原因。所以一开始,我使用以下脚本确认了这一点。

var spreadsheetId = "#####";
var range = "'Copie de Feuille 1'!A1:JE1000";
var url = "https://sheets.googleapis.com/v4/spreadsheets/" + spreadsheetId + "/values/" + range + "?majorDimension=ROWS&valueRenderOption=FORMULA";
var res = UrlFetchApp.fetch(url, {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}});
Logger.log(res.getContentText().length.toString())
var values = JSON.parse(res.getContentText());

运行上述脚本时,返回 52428450。最后一行出现“Unterminated string literal”错误。这意味着该对象是不完整的。从这个结果可以看出,在 'Copie de Feuille 1'!A1:JE1000 范围内调用一次 values.get 是无法取回值的。这与 I'-'I`s comment 的情况相同。 .

在您的示例电子表格中,发现发生错误的范围边界是'Copie de Feuille 1'!A1:JE722。当尝试从范围 'Copie de Feuille 1'!A1:JE723 中检索值时,会发生错误。从 'Copie de Feuille 1'!A1:JE722 中检索到的值的大小为 52,390,229 字节。这小于 50 MB(52,428,800 字节)。 'Copie de Feuille 1'!A1:JE723 的大小为 52,428,450 字节,与 'Copie de Feuille 1'!A1:JE1000 的值相同。由此,发现超出了UrlFetchApp的限制。

解决方法:

为了避免此错误并检索所有值,作为一种解决方法,我想我想建议它拆分从电子表格检索值的范围。但在你的问题中,你想要速度。因此,我想提出以下示例脚本。

  1. 创建请求。
  2. 使用 UrlFetchApp.fetchAll() 获取创建的请求。
    • 通过UrlFetchApp.fetchAll(),每个请求都可以异步处理。
    • 在 Advanced Google Service 的 Sheets API 中,无法使用。而且,在values.batchGet,因为所有检索到的值都超过了限制,所以发生了错误。
    • 由此,使用 UrlFetchApp.fetchAll() 的处理成本变得低于 Advanced Google Service 的 Sheets API。

示例脚本:

var ranges = ["'Copie de Feuille 1'!A1:JE500", "'Copie de Feuille 1'!A501:JE1000"]; // This was used from the shared spreadsheet. So please modify this for your environment.
var token = ScriptApp.getOAuthToken();
var requests = ranges.map(function(e) {
  return {
    method: "get",
    url: "https://sheets.googleapis.com/v4/spreadsheets/" + spreadsheetId + "/values/" + e + "?majorDimension=ROWS&valueRenderOption=FORMULA",
    headers: {Authorization: "Bearer " + token},
    muteHttpExceptions: true,
  }
});
var res = UrlFetchApp.fetchAll(requests);
var values = res.reduce(function(ar, e) {
  Array.prototype.push.apply(ar, JSON.parse(e.getContentText()).values);
  return ar;
}, []);
Logger.log(values.length) // 1000
Logger.log(values[0].length) // 265

备注:

  • 如果您想使用该脚本,请确认已在 API 控制台启用 Sheets API。
  • 数组合并时,如果出现数组限制错误,请使用每个数组,不要合并数组。
  • 使用 Advanced Google Service 的 Sheets API 时,在 'Copie de Feuille 1'!A1:JE722 范围内也没有发生错误,而在 'Copie de Feuille 1'!A1:JE723。此结果与 UrlFetchApp 的结果相同。

引用资料:

关于javascript - 未记录的 Sheet API 限制问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52900410/

相关文章:

javascript - 屏幕导航标题不会显示在堆叠的抽屉导航中....React Navigation V2

email - MailApp.sendEmail 在 google apps 脚本中未设置时向自己发送电子邮件

google-apps-script - (Gmail) 从电子表格发送电子邮件。如何添加带有图像的签名?

google-sheets - 如何使用 Google Sheets Api V4 检索带有格式的工作表数据

google-api - 服务帐户是否被视为 Google Sheets API v4 使用限制中的用户?

google-apps-script - 单元格是公式吗?在谷歌脚本中

javascript - 如何设置值数组以动态接受 Angular 4中输入标签的属性

javascript - 使用 Mongoose 和 Typescript,接口(interface)的 ref 字段应该使用什么类型?

javascript - 切换多个复选框 – 原型(prototype) js

javascript - 单击新窗口,在新窗口中更改元素