应用脚本:如何在 Google Sheet 中返回 BigQuery-Request 的 TotalRows

Posted

技术标签:

【中文标题】应用脚本:如何在 Google Sheet 中返回 BigQuery-Request 的 TotalRows【英文标题】:App Script: how to return TotalRows of a BigQuery-Request in Google Sheet 【发布时间】:2020-11-09 08:28:07 【问题描述】:

我为 Google Sheet 编写了一个应用脚本,用于更新 BQ 中的表格。该脚本应返回表的总行数以及其他信息。该脚本返回作业状态和总字节数,但不返回总行数。我没有看到不同值之间的区别:https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/getQueryResults

为了获得 TotalRows,我必须进行哪些更改?

  // Need to provoke a drive dialog
  // DriveApp.getFiles()
  
  // Replace this value with your project ID and the name of the sheet to update.
  var projectId = 'my-project';
  var sheetName = 'my-sheet';

  // Use standard SQL to query BigQuery
  var request = 
    query: 'DROP TABLE `my-project.xyz.targetgroup_5_tbl`; CREATE TABLE `my-project.xyz.targetgroup_5_tbl` AS SELECT * FROM `waipu-app-prod.Access.targetgroup_5_std`;',
    useLegacySql: false
  ;
  var queryResults = BigQuery.Jobs.query(request, projectId);
  var jobId = queryResults.jobReference.jobId;


  // Check on status of the Query Job.
  var sleepTimeMs = 500;
  while (!queryResults.jobComplete) 
    Utilities.sleep(sleepTimeMs);
    sleepTimeMs *= 2;
    queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
  
  
  if (queryResults.jobComplete=true) 
    // Append the results.
    var status= queryResults.jobComplete;
    var dayc = new Date();
    var totalbytes = queryResults.totalBytesProcessed;
    var totalRows = queryResults.totalRows;

    var rows = [
                   ['target group',status,dayc,totalbytes,totalRows],      
               ]
    var status = queryResults.jobComplete; 
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var currentSheet = ss.getSheetByName(sheetName);
    currentSheet.getRange(23,1, 1, 5).setValues(rows);
    
    console.info('%d rows inserted.', queryResults.totalRows);
   else 
    console.info('No results found in BigQuery');
  

```

【问题讨论】:

【参考方案1】:

代码只是有一个小错误,在其中一个比较中,您使用了:

if (queryResults.jobComplete=true)

这总是会评估为真,因为这是一个分配,而不是比较。要比较 jobComplete 是否为真,您应该改用 '==',即,

if (queryResults.jobComplete==true)

甚至更好,因为 jobComplete 已经是一个布尔变量,你可以简单地这样做:

if (queryResults.jobComplete)

现在,您没有收到 totalRows 的原因是因为您正在执行一个不返回任何行的 sql 脚本。即使您只考虑脚本的最后一部分,您也正在执行 CREATE TABLE AS 语句,它不会返回任何行。

我了解到您想知道在此表中插入了多少行。有很多选项可以这样做,包括获取表详细信息,或执行SELECT COUNT 查询;但是,根据您在 sql 脚本中所做的操作:删除并重新创建表,我建议您采用不同的方法:使用 API 方法 Jobs.insert 指定目标表,以便您可以将查询作为 @987654328 执行@ 陈述。最后,使用writeDisposition:"WRITE_TRUNCATE" 删除之前的数据,就像在您的脚本中一样。

这里有一段代码可以作为参考:

var projectId = 'my-project';

// The request object changed to adapt to a Jobs.insert request
var request = 
  configuration: 
    query: 
      destinationTable: 
        projectId: projectId,
        datasetId: 'my-dataset',
        tableId: 'my-table'
      ,
      query: 'SELECT * FROM ...', // Here goes the query used to create the table
      useLegacySql: false,
      writeDisposition: 'WRITE_TRUNCATE' // Truncate the data before writing it again
    
  
;

var queryResults = BigQuery.Jobs.insert(request, projectId); // Use Jobs.insert instead of Jobs.query
var jobId = queryResults.jobReference.jobId;

【讨论】:

太棒了!成功了 :-) 非常感谢@Tlaquetzal!

以上是关于应用脚本:如何在 Google Sheet 中返回 BigQuery-Request 的 TotalRows的主要内容,如果未能解决你的问题,请参考以下文章

直接在 Apps 脚本中按单元格颜色对 google-sheet 值进行排序

在 Google Sheet 模板的容器绑定脚本中维护启用的 API

如何将自定义菜单添加到Google Sheet Addon

使用 Google App 脚本更改 Google Sheet 中部分单元格值的字体粗细

在 Google Apps 脚本中使用 BigQuery 连接到 Google 电子表格

通过 Drive API 自动执行 Google Sheet 操作(制作副本、Google App 脚本、触发器)