从 Google 电子表格请求 BigQuery API 会产生错误

Posted

技术标签:

【中文标题】从 Google 电子表格请求 BigQuery API 会产生错误【英文标题】:Requesting a BigQuery API from Google Spreadsheet generates an Error 【发布时间】:2020-07-24 15:27:46 【问题描述】:

我正在尝试从 Bigquery 获取数据并使用 App 脚本将它们显示到我的电子表格中。首先,我在 G 盘中创建了一个电子表格文件,然后将我的代码放入脚本编辑器中。

这是我用来从 Bigquery 获取所有数据集的代码:

    function getAllDataSets(filter)
  try
    let req_for_datasets = BigQuery.Datasets.list(PROJECT_ID);
    let datasets = req_for_datasets.datasets;
    let list = [];
    datasets.forEach( obj => 
      if(obj.datasetReference.datasetId.indexOf(filter)>-1) 
        list.push(obj.datasetReference.datasetId);
    );
    return list;
  catch(e)
    return [];
  

这个脚本运行良好,我可以在通过代码编辑器运行我的脚本时看到结果。我尝试在 onOpen() 或 onEdit() 中使用此脚本,以便在打开电子表格时能够获取数据。 但使用电子表格我收到了这条消息:

GoogleJsonResponseException: API call to bigquery.tables.list failed with error: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential.

这是我放在 onOpen 函数中的代码:

    function onOpen()
  let ui = SpreadsheetApp.getUi();
  let method_list = ["SUM", "AVG", "COUNT"];
  //Adding a Custom menu
  ui.createMenu("Media Budget")
    .addItem("Facebook", "makeQuery")
    .addSeparator()
    .addItem("Google Ads", "makeQuery")
    .addToUi();

    
  //Getting all datasets from the specified project
  let dataset_list = getAllDataSets("dw_sandbox_");
  Browser.msgBox(dataset_list);
  //Creating dropdown list cell
  let cell = SHEET.getRange("B1");
  applyValidationToCell(dataset_list, cell);
  

除此之外,如果我尝试使用电子表格中的自定义菜单执行该功能,一切正常。

如果您能帮助我,将不胜感激。

【问题讨论】:

【参考方案1】:

如果您可以在手动运行代码时执行请求,但不能在简单的 onOpen 或 onEdit 触发器上执行 - 原因是授权问题

见restrictions:

因为简单的触发器会自动触发,无需询问用户 对于授权,它们受到一些限制:

...

他们无法访问需要授权的服务。例如,一个 简单触发器无法发送电子邮件,因为 Gmail 服务需要 授权,但一个简单的触发器可以翻译一个短语 语言服务,是匿名的。

解决方法

选项 a)

与其运行请求onOpen,不如将​​其实现为一个单独的函数,当从自定义菜单中选择该函数时将调用该函数

示例:

function onOpen()
  let ui = SpreadsheetApp.getUi();
  let method_list = ["SUM", "AVG", "COUNT"];
  //Adding a Custom menu
  ui.createMenu("Media Budget")
  .addItem("Facebook", "makeQuery")
  .addSeparator()
  .addItem("Google Ads", "makeQuery")
  .addSeparator()
  .addItem("bigQuery", "makeBigQuery")
  .addToUi();  


function makeBigQuery()
  //Getting all datasets from the specified project
  let dataset_list = getAllDataSets("dw_sandbox_");
  Browser.msgBox(dataset_list);
  //Creating dropdown list cell
  let cell = SHEET.getRange("B1");
    applyValidationToCell(dataset_list, cell);

选项 b)

在installable 上运行现有代码,而不是在简单触发器上运行。

可安装的触发器可以运行需要授权的功能

将您的简单触发器转换为可安装的触发器

将函数从 onOpen 重命名(否则您可能会因为同时运行简单触发器和可安装触发器而遇到冲突) 继续Edit -> Current project's triggers - > New trigger - 另见here

【讨论】:

以上是关于从 Google 电子表格请求 BigQuery API 会产生错误的主要内容,如果未能解决你的问题,请参考以下文章

用于将数据从谷歌电子表格加载到 bigquery 的独立脚本

使用来自 bigquery 的数据自动更新 google 电子表格

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

使用来自 Google BigQuery 的数据更新电子表格不起作用

新 Google 电子表格的 BigQuery 访问权限

无法在 Google 电子表格中运行 BigQuery.Jobs.query