google-sheets - 如何验证服务帐户以对 GDrive Sheet 支持的 BigQuery 表进行查询?

标签 google-sheets google-bigquery google-cloud-platform google-spreadsheet-api

我的情况如下:

Google 帐户 A 在 BigQuery 中有一些数据。

Google 帐户 B 管理帐户 A 的 BigQuery 数据,并且还获得了帐户 A 的 Cloud Platform 项目的编辑权限。

帐户 B 在 Google Drive 中有一张表格,里面有一些很酷的引用数据。账户 B 登录到 BQ Web 控制台,并在账户 A 的 BQ 项目中创建一个由该表支持的表。

一切都很好。账户 B 可以通过 Web UI 在账户 A 的 BQ 数据中成功查询并加入该表。

问题:

Google 帐户 A 还有一个服务帐户,它是 Google 帐户 A 的云平台项目的编辑器。此服务帐户使用 python google-cloud API 管理和查询 BQ 中的数据。当此服务帐户尝试查询由帐户 B 的 GDrive 表支持的引用表时,作业失败并出现以下错误:

Encountered an error while globbing file pattern.  JobID: "testing_gdrivesheet_query_job1"

据我所知,这实际上是一个身份验证问题。如何为账户 A 的服务账户授予对账户 B 的 GDrive 的适当访问权限,以便它可以访问该引用表?

奖励积分:
GDrive Sheet 支持的表与 native BQ 表之间是否存在性能差异?

最佳答案

虽然 Orbit 的回答帮助我找到了解决该问题的方法,但您还需要考虑一些其他事项。因此,我喜欢添加我对问题的详细解决方案。如果 Orbit 的基本解决方案不起作用,则需要此解决方案,特别是如果您使用 G Suite并且您的政策不允许与域外的帐户共享工作表/文档。在这种情况下,您不能直接与服务帐户共享文档/工作表。

在你开始前:

  • 创建或选择 service account在您的项目中
  • DwD 中启用域范围委派 (account settings) .如果不存在,则会为服务帐户生成 OAuth 客户端 ID。
  • 确保委托(delegate) user@company.com可以访问工作表。
  • 将所需的范围添加到您的服务帐户的 OAuth 客户端(您可能需要让 G Suite 管理员为您执行此操作):
  • https://www.googleapis.com/auth/bigquery
  • https://www.googleapis.com/auth/drive

  • 如果委派用户可以在 BigQuery UI 中访问您基于驱动器的表,那么您的服务帐号现在应该也能够代表委派用户访问它。

    这是一个对我有用的完整代码片段:
    #!/usr/bin/env python
    
    import httplib2
    from google.cloud import bigquery
    from oauth2client.service_account import ServiceAccountCredentials
    
    scopes = [
        "https://www.googleapis.com/auth/drive",
        "https://www.googleapis.com/auth/bigquery",
    ]
    
    delegated_user = "user@example.com"
    project        = 'project-name'
    table          = 'dataset-name.table-name'
    query          = 'SELECT count(*) FROM [%s:%s]' % (project, table)
    
    creds = ServiceAccountCredentials.from_json_keyfile_name('secret.json', scopes=scopes)
    creds = creds.create_delegated(delegated_user)
    
    http = creds.authorize(httplib2.Http())
    client = bigquery.Client(http=http)
    
    bq = client.run_sync_query(query)
    bq.run()
    print bq.fetch_data()
    

    请注意,我无法直接设置委托(delegate),需要使用 creds = creds.create_delegated(delegated_user) 创建 HTTP 客户端。和 http = creds.authorize(httplib2.Http()) .然后可以将授权的 HTTP 客户端用作 BigQuery 客户端的 HTTP 客户端:client = bigquery.Client(http=http) .

    另请注意,服务帐户不需要在项目设置中分配任何预定义角色,即,您不必将其设为 bigquery 用户甚至项目所有者。我想它主要通过委托(delegate)获得访问权限。

    关于google-sheets - 如何验证服务帐户以对 GDrive Sheet 支持的 BigQuery 表进行查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40391128/

    相关文章:

    google-sheets - 是否有一个公式可以计算单元格中使用 "@"的次数?

    google-sheets - 如何检测 Google 表格中合并了哪些单元格

    sql - 如何使用 BigQuery 按月-年分组

    google-cloud-platform - 为什么在 Cloud Composer 中会自动生成一个名为 'airflow_monitoring' 的 DAG?

    google-apps-script - 这些列在 autoResizeColumns 方法中出现越界错误

    javascript - BigQuery 用户定义函数中的 Base64 编码

    将 CSV 数据从 Google 存储加载到 Bigquery 的 Python 代码?

    Golang GCP 存储客户端内存泄漏

    node.js - 如何使用multer和NodeJS将图像上传到GCS存储桶?

    google-apps-script - 从一列收集所有唯一值并将它们输出到另一列中..?