简体   繁体   English

绑定的 AppsScript Google 表格中超出 Memory 限制 function

[英]Memory limit exceeded in AppsScript Google Sheets bound function

Have you ever met the cases when the owner of Google Sheets doesn't have the "Exceeded memory limit" error when running bound script, and the editor of the same document does?您是否遇到过 Google Sheets 的所有者在运行绑定脚本时没有出现“Exceeded memory 限制”错误,而同一文档的编辑器却出现这种情况?

I have a report in Google Sheets which is created as the result of API request to Google BigQuery.我在 Google 表格中有一份报告,该报告是由于对 Google BigQuery 的 API 请求而创建的。 Here's my bound script (I excluded the full SQLquery text, because it's not the issue):这是我的绑定脚本(我排除了完整的 SQLquery 文本,因为这不是问题):

function Report_detailed() {
   var t = new Array(0);
  var projectId = 'project_id';
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Detailed_report");
  var result = sheet; 
  var dateFrom =  Utilities.formatDate(new Date(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Detailed_report").getRange("B1:B1").getValue()),"GMT+3", "yyyy-MM-dd");
  var dateTo =  Utilities.formatDate(new Date(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Detailed_report").getRange("B2:B2").getValue()),"GMT+3", "yyyy-MM-dd");
  var lastRow = sheet.getLastRow();
  sheet.getRange(6,1,lastRow,55).clearContent(); 
  var cell = sheet.getRange("G6:BC");
  cell.setNumberFormat("0.00");
  var request = {
        query: 
'                SELECT * '+
'                FROM '+
'                `project_id.dataset_id.table_name` '+ 
'                WHERE '+    
'                date  BETWEEN "'+dateFrom+'" AND "'+dateTo+'" ',    
        useLegacySql: "FALSE",
  } ;
  t[0] = new Date();
  t[0] = 'Stage 1'+t[0];
  var queryResults = BigQuery.Jobs.query(request, projectId);
  t[1] = new Date();
  t[1] = 'Stage 2'+t[1];
  var jobId = queryResults.jobReference.jobId;

    // Check on status of the Query Job.
  var sleepTimeMs = 1000;
  var n = 0;
  while (!queryResults.jobComplete) {
    n = n + 1;
    Utilities.sleep(sleepTimeMs);
    sleepTimeMs *= 2;
    queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
  }
  t[2] = new Date();
  t[2] = 'Stage 3'+t[2];
  Logger.log ('jobs');

  // Get all the rows of results.
  var rows = queryResults.rows;
  while (queryResults.pageToken) {
    queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
      pageToken: queryResults.pageToken,
    });
    rows = rows.concat(queryResults.rows);
  }
  t[3] = new Date();
  t[3] = 'Stage 4'+t[3];
  if (rows) {

    // Append the results.
    var data = new Array(rows.length);
    for (var i = 0; i < rows.length; i++) {
      var cols = rows[i].f;
      data[i] = new Array(cols.length);
      for (var j = 0; j < cols.length; j++) {
        data[i][j] = cols[j].v;
      }
    }
    t[4] = new Date();
    t[4] = 'Stage 5'+t[4];
      Logger.log ('datas');

    sheet.getRange(6, 1, rows.length, 55).setValues(data);
    t[5] = new Date();
    t[5] = 'Stage 6'+t[5];    
    Logger.log(t.join('\\n'));

    Logger.log('Results spreadsheet created: %s');
  } else {
    Logger.log('No rows returned.');
  }
  return n;
}

Additional info:附加信息:

  1. The function is called from UI.从 UI 调用 function。
  2. The query size is about 100 MB, so it's performed very fast.查询大小约为 100 MB,因此执行速度非常快。
  3. The first 4 stages are run in 1-2 minutes前 4 个阶段在 1-2 分钟内运行
  4. The result table has about 25 000 rows.结果表有大约 25 000 行。 So the longest part of the process is setting values to the cells.因此,该过程中最长的部分是为单元格设置值。
  5. The Sheets locale is the US, the owner is in Ukraine, the editors of the file are in the other country.表格区域设置为美国,所有者在乌克兰,文件的编辑在其他国家/地区。

When I run the function from my Google Account, everyting's OK, and I get the result table in 5-6 minutes.当我从我的 Google 帐户运行 function 时,一切正常,我在 5-6 分钟内得到结果表。

But when my colleagues from the other country try to refresh the report in their Google Accounts, applying the same date range as I do, they have "Memory limit exceeded" without any detailed explanations.但是,当我来自其他国家/地区的同事尝试在他们的 Google 帐户中刷新报告时,应用与我相同的日期范围,他们没有任何详细解释就出现“超出内存限制”。

Could you please help me to find the roots of the issue?你能帮我找出问题的根源吗?

I'd appreciate any clues and recommendations.我会很感激任何线索和建议。 Thank you so much!太感谢了!

Troubleshooting故障排除

Check for file access检查文件访问

Do all your users have access to the data you are trying to retrieve?您的所有用户都可以访问您尝试检索的数据吗?

Encapsulate your code with try catchtry catch封装你的代码

If your code is failing due to a Query issue, encapsulate it with try catch and Log the errors.如果您的代码由于查询问题而失败,请使用try catch将其封装并Log错误。

Monitor the execution and determine where it breaks监控执行并确定它在哪里中断

Use the Apps Script Debugger to determine in which step your code fails and what the variables look like when it does.使用Apps Script Debugger确定您的代码在哪一步失败,以及当它失败时变量的样子。

Check Quotas and Limits检查配额和限制

Check the quotas and limits and determine if you have exceeded them.检查配额和限制并确定您是否超出了它们。 Error messages will point you to this by saying that you were timed out or have to wait before trying again.错误消息会指出您已超时或必须等待才能重试。

Script Execution timeout脚本执行超时

Apps script also has their own quotas , make sure your code can be executed in the time-frame determined. Apps 脚本也有自己的配额,请确保您的代码可以在确定的时间范围内执行。 Specially when dealing with Data In/Out, it's important to use Batch operations.特别是在处理数据输入/输出时,使用批处理操作很重要。

If all else fails...如果一切都失败了......

Contact G Suite Support for your domain.联系您所在域的 G Suite 支持

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM