我正在开发应用脚本,以定期检查Web服务上的已修改项目。由于API调用耗时太长,我一直试图在ScriptDb中定期缓存一些数据。但是,尝试使用scriptDb.saveBatch
更新数据始终会导致以下错误:
Service invoked too many times in a short time: scriptdb rateMax. Try Utilities.sleep(1000) between calls.
我的脚本正在查询ScriptDb并返回约7600条记录的结果集,修改这些记录,然后将所有内容保存回批处理中。考虑到Google提供的工具,我无法以任何方式考虑减少我所做的数据库调用次数。这对ScriptDb来说真的太过难以处理,还是有一些方法可以改进我的代码?
function getRootFolders() {
var updateTimestamp = new Date().valueOf();
var results = GetModifiedFolders(ROOT_FOLDER); //Returns results from an API call
var data = results.data; //The actual data from the API, as an array
var len = data.length;
if (len > 0) {
//Get a collection of dbMaps from ScriptDb
var maps = {}; //Store as an object for easy updating
var getMaps = db.query({'type': 'baseFolder'}).limit(50000); //Returns 7621 items
while (getMaps.hasNext()) {
var map = getMaps.next();
maps[map.boxId] = map;
}
//Iterate through the results
for (i = 0; i < len; i++) {
var item = data[i];
var map = maps[item.boxId]; //Try to retrive an existing dbMap
if (map) { //If it exists, update the existing dbMap
map.modified = item.modified;
map.updateTimestamp = updateTimestamp;
}
else { //Otherwise, insert the result into the collection of dbMaps
item.type = 'baseFolder';
item.updateTimestamp = updateTimestamp;
maps[item.boxId] = item;
}
}
//Convert the object back to an array, and use that to save to ScriptDb
var toSave = [];
for (var prop in dbMaps) {
toSave.push(dbMaps[prop]);
}
var mutations = db.saveBatch(toSave, false); //FAIL with scriptdb rateMax
if (db.allOk(mutations)) {
( . . . )
}
}
}
修改
为了阻止这种情况的发生,我做了一些改变,但无济于事。我在打电话给saveBatch
,和之前已经睡了几分钟,然后我会在多个较小的批次中保存,并在每个之间睡觉。
此时,我无法想象为什么我仍然会收到此rateMax错误。我错过了我的代码是否有问题,或者这是应用程序脚本中的错误?我认为这是我的错,但我无法看到它。
以下是我添加的内容:
//Retrieving data from the API takes ~1 minute
//Sleep for a while to avoid rateMax error
var waitUntil = updateTimestamp + 240000; //Wait until there's only 1 minute left in the 5 minute quota
var msToWait = waitUntil - (now.valueOf());
Utilities.sleep(msToWait); //Sleep for ~3 minutes
//Save in batches
var batchSize = 250;
var batch = [];
var i = 0;
for (var prop in maps) {
batch.push(maps[prop]);
i++;
//When the batch reaches full size, save it
if (i % batchSize == 0 || i == len) {
Utilities.sleep(1000);
var mutations = db.saveBatch(batch, false);
if (!db.allOk(mutations)) {
return false;
}
batch = [];
}
}
答案 0 :(得分:1)
将批次拆分成较小的部分。 不会影响代码,因为批次不是原子的。