You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Apps Script中通过Service Account调用BigQuery API查询VPC项目数据

1. VPC项目执行BigQuery作业是否需要Service Account

如果你的VPC项目开启了VPC Service Controls、或者配置了个人账号访问BigQuery的权限限制,或者你开发的Data Studio社区连接器需要对所有访问用户统一授权,就必须使用Service Account发起请求。如果你的个人账号已经被加入VPC项目的权限白名单、同时在VPC SC的允许访问主体列表里,也可以用个人身份执行,但可复用性和安全性远低于服务账号方案。

2. Service Account授权配置步骤

  • 第一步:在VPC所属的GCP项目中创建Service Account,为其分配最小必要权限:roles/bigquery.jobUser(用于提交查询作业)、对应数据集的roles/bigquery.dataViewer(用于读取查询目标表数据),如果开启了VPC Service Controls,需要将该服务账号加入对应访问边界的允许主体列表中。
  • 第二步:为该Service Account创建JSON格式的密钥文件,下载保存到本地。
  • 第三步:在Apps Script项目中添加OAuth2 for Apps Script库,替换原有内置BigQuery高级服务的调用逻辑,使用服务账号令牌发起API请求,示例代码如下:
// 服务账号授权配置
function getOAuthService() {
  const serviceAccountKey = {
    "private_key": "你下载的JSON密钥里的private_key内容",
    "client_email": "你下载的JSON密钥里的client_email内容"
  };
  return OAuth2.createService('BigQueryServiceAccount')
    .setTokenUrl('https://oauth2.googleapis.com/token')
    .setPrivateKey(serviceAccountKey.private_key)
    .setIssuer(serviceAccountKey.client_email)
    .setScope('https://www.googleapis.com/auth/bigquery')
    .setCache(CacheService.getScriptCache())
    .setProperties(PropertiesService.getScriptProperties());
}

// 改造后的查询方法
function runQuery() {
  const sql = "SELECT Distinct ss_cd FROM `vf-pt-ngbi-dev-gen-03.AEAD_DataSet_test.d_customer` WHERE end_dttm IS NOT NULL";
  const projectId = "你的VPC项目ID";
  const service = getOAuthService();
  if (!service.hasAccess()) {
    Logger.log('授权失败: ' + service.getLastError());
    return;
  }
  // 手动调用BigQuery API
  const apiUrl = `https://bigquery.googleapis.com/bigquery/v2/projects/${projectId}/queries`;
  const payload = JSON.stringify({
    query: sql,
    timeoutMs: 100000,
    useLegacySql: false
  });
  const options = {
    method: 'POST',
    contentType: 'application/json',
    headers: {
      Authorization: 'Bearer ' + service.getAccessToken()
    },
    payload: payload
  };
  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const queryResults = JSON.parse(response.getContentText());
    // 把结果存入数组
    const resultArray = queryResults.rows.map(row => row.f[0].v);
    Logger.log(resultArray);
    return resultArray;
  } catch (err) {
    Logger.log(err);
    return;
  }
}

3. 其他可行方案

  • 方案1:在VPC内部署Cloud Function/Cloud Run服务,将BigQuery查询逻辑封装成HTTP接口,Apps Script通过调用该接口获取查询结果,接口直接返回JSON格式数据,转换为数组即可使用。该方案无需在Apps Script侧配置复杂的服务账号授权,云服务本身运行在VPC内,天然符合网络权限要求。
  • 方案2:提前将查询结果定时同步到BigQuery的中间表,Apps Script只需读取中间表数据即可,适合查询逻辑固定、数据实时性要求不高的场景,可减少重复查询的资源消耗。
  • 方案3:如果你的VPC配置了VPN或者专线连通本地环境,也可以在本地部署定时任务执行BigQuery查询,将结果同步到Apps Script可访问的存储位置(比如Google Sheets、Cloud Storage),再由Apps Script读取存入数组。

内容的提问来源于stack exchange,提问作者Joao Simoes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 19:57:03