Javascript 未记录的工作表API限制问题
我已经看过有人遇到类似问题的帖子,但找不到明确的答案 我尝试使用以下代码行检索264735个插槽的2D阵列:Javascript 未记录的工作表API限制问题,javascript,google-apps-script,google-sheets-api,http-status-code-413,Javascript,Google Apps Script,Google Sheets Api,Http Status Code 413,我已经看过有人遇到类似问题的帖子,但找不到明确的答案 我尝试使用以下代码行检索264735个插槽的2D阵列: var optionalArguments = {majorDimension: "ROWS", valueRenderOption: "FORMULA", }; var sourceValuesObject = Sheets.Spreadsheets.Values.get(spreadsheetId, rangeA1Notation
var optionalArguments = {majorDimension: "ROWS",
valueRenderOption: "FORMULA",
};
var sourceValuesObject = Sheets.Spreadsheets.Values.get(spreadsheetId, rangeA1Notation, optionalArguments)
但我得到的是:
答复代码:413。消息:响应太大
这看起来很奇怪,因为我看不到这种无处书写的限制,加上如果300000个或更少的单元格导致API错误,用户如何获取大量数据
我尝试过拆分请求,但这会使我的代码变得更复杂、更慢,而且当我尝试将值更新回工作表的范围时,会得到一个空响应
我指的方向对吗?这正常吗?有解决办法吗
编辑:
首先,我尝试使用Sheets.Spreadsheets.Values.get
在for
循环中,它工作了
使用
batchGet
执行相同的操作会产生相同的错误,因此我想我的单元格中的数据太大了。这个解决方法怎么样
实验:
此实验使用共享的示例电子表格
当URL FetchApp直接调用Sheets API的端点时,如果响应大小大于50 MB(52428800字节),则返回小于50 MB的响应。50MB的大小是由于UrlFetchApp的限制。另一方面,在AdvancedGoogle服务中,它无法确认这种情况,因为错误发生在超过限制时。因此,通过使用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”错误。这意味着对象是不完整的。从这个结果可以发现,一次调用values.get的范围为'Copie de Feuille 1',无法检索到这些值!A1:JE1000
。这是同样的情况
在您的示例电子表格中,发现错误发生的范围边界是“Copie de Feuille 1”!A1:JE722
。尝试从范围'Copie de Feuille 1'检索值时!A1:JE723
,发生错误。从'Copie de Feuille 1'检索到的值的大小!A1:JE722是52390229字节。这小于50MB(52428800字节)。来自'Copie de Feuille 1'的尺寸!A1:JE723
是52428450字节,这与的“Copie de Feuille 1”中的值相同!A1:JE1000
。由此可以看出,它超出了UrlFetchApp的限制
解决方法:
为了避免此错误并检索所有值,作为一种解决方法,我想我建议将从电子表格检索值的范围分开。但在你的问题中,你想要的是速度。因此,我想提出以下示例脚本
创建请求
使用UrlFetchApp.fetchAll()
获取创建的请求。
- 通过
UrlFetchApp.fetchAll()
,每个请求都可以通过异步处理工作
- 在高级谷歌服务的API中,这是不能使用的。此外,在values.batchGet,由于所有检索到的值都超过了限制,因此会发生错误
- 这样,使用
UrlFetchApp.fetchAll()
的过程成本就比使用高级Google服务的Sheets API的过程成本要低
示例脚本:
注:
- 如果要使用该脚本,请确认在API控制台上启用了Sheets API
- 合并数组时,如果出现数组限制错误,请在不合并数组的情况下使用每个数组
- 当使用高级Google服务的API时,
“Copie de Feuille 1”范围内也不会发生错误!A1:JE722
错误发生在“Copie de Feuille 1”!A1:JE723
。此结果与UrlFetchApp
的结果相同
参考资料:
下面是我通过比较不同的获取价值的方法得到的结果:
function compare(){
getValuesSpreasheetApp();
getValuesUrlFetch();
getValues();
}
//using spreadsheetApp.getFormulas()
function getValuesSpreasheetApp(){
var t0 = new Date().getTime();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataRange = ss.getActiveSheet().getDataRange();
var formulas = dataRange.getFormulas();
var values = dataRange.getValues();
var t1 = new Date().getTime();
Logger.log("spreadsheetApp: " + (t1 -t0));
}
//using UrlFetchApp.fetchAll
function getValuesUrlFetch()
{
var t0 = new Date().getTime();
var ranges = ["'Copie de Feuille 1'!A1:JE500", "'Copie de Feuille 1'!A501:JE1000"];
var token = ScriptApp.getOAuthToken();
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
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;
}, []);
var t1 = new Date().getTime();
Logger.log("UrlFetch: " + (t1 -t0));
}
//using Sheets.Spreadsheets.Values.get()
function getValues(){
var t0 = new Date().getTime();
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
var ranges = ["'Copie de Feuille 1'!A1:JE500", "'Copie de Feuille 1'!A501:JE1000"];
var optionalArguments = {majorDimension: "ROWS",
valueRenderOption: "FORMULA",
};
res = [];
for(var i = 0; i < ranges.length; i++)
res.push(Sheets.Spreadsheets.Values.get(spreadsheetId, ranges[i]));
var values = res.reduce(function(ar, e) {
Array.prototype.push.apply(ar, e.values);
return ar;
}, []);
var t1 = new Date().getTime();
Logger.log("values.get: " + (t1 -t0));
}
函数比较(){
GetValuesPreasheetApp();
getValuesUrlFetch();
getValues();
}
//使用spreadsheetApp.getFormulas()
函数GetValuesPreasheetApp(){
var t0=新日期().getTime();
var ss=SpreadsheetApp.getActiveSpreadsheet();
var dataRange=ss.getActiveSheet().getDataRange();
var formulas=dataRange.getFormulas();
var values=dataRange.getValues();
var t1=new Date().getTime();
Logger.log(“电子表格应用程序:”+(t1-t0));
}
//使用UrlFetchApp.fetchAll
函数getValuesUrlFetch()
{
var t0=新日期().getTime();
变量范围=[“'Copie de Feuille 1'!A1:JE500”、“'Copie de Feuille 1'!A501:JE1000”];
var token=ScriptApp.getOAuthToken();
var spreadsheetId=SpreadsheetApp.getActiveSpreadsheet().getId();
var请求=ranges.map(函数(e){
返回{
方法:“获取”,
url:“https://sheets.googleapis.com/v4/spreadsheets/“+spreadsheetId+”/values/“+e+”?主尺寸=行和值渲染=公式”,
标头:{授权:“承载者”+令牌},
muteHttpExceptions:true,
}
});
var res=UrlFetchApp.fetchAll(请求);
var值=res.reduce(函数(ar,e){
Array.prototype.push.apply(ar,JSON.parse(e.getContentText()).values);
返回ar;
}, []);
var t1=new Date().getTime();
log(“UrlFetch:”+(t1-t0));
}
//使用Sheets.Spreadsheets.Values.get()
函数getValues(){
var t0=新日期().getTime();
var spreadsheetId=SpreadsheetApp.getActiveSpreadsheet().getId();
变量范围=[“'Copie de Feuille 1'!A1:JE500”、“'Copie de Feuille 1'!A501:JE1000”];
var optionalArguments={majorDimension:“行”,
valueRenderOption:“公式”,
};
res=[];
对于(变量i=0;ifunction compare(){
getValuesSpreasheetApp();
getValuesUrlFetch();
getValues();
}
//using spreadsheetApp.getFormulas()
function getValuesSpreasheetApp(){
var t0 = new Date().getTime();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataRange = ss.getActiveSheet().getDataRange();
var formulas = dataRange.getFormulas();
var values = dataRange.getValues();
var t1 = new Date().getTime();
Logger.log("spreadsheetApp: " + (t1 -t0));
}
//using UrlFetchApp.fetchAll
function getValuesUrlFetch()
{
var t0 = new Date().getTime();
var ranges = ["'Copie de Feuille 1'!A1:JE500", "'Copie de Feuille 1'!A501:JE1000"];
var token = ScriptApp.getOAuthToken();
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
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;
}, []);
var t1 = new Date().getTime();
Logger.log("UrlFetch: " + (t1 -t0));
}
//using Sheets.Spreadsheets.Values.get()
function getValues(){
var t0 = new Date().getTime();
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
var ranges = ["'Copie de Feuille 1'!A1:JE500", "'Copie de Feuille 1'!A501:JE1000"];
var optionalArguments = {majorDimension: "ROWS",
valueRenderOption: "FORMULA",
};
res = [];
for(var i = 0; i < ranges.length; i++)
res.push(Sheets.Spreadsheets.Values.get(spreadsheetId, ranges[i]));
var values = res.reduce(function(ar, e) {
Array.prototype.push.apply(ar, e.values);
return ar;
}, []);
var t1 = new Date().getTime();
Logger.log("values.get: " + (t1 -t0));
}