【问题标题】:How do I Authenticate a Service Account to Make Queries against a GDrive Sheet Backed BigQuery Table?如何验证服务帐户以对 GDrive Sheet 支持的 BigQuery 表进行查询?
【发布时间】:2017-03-16 10:12:41
【问题描述】:

我的情况如下:

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

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

帐户 B 在 Google 云端硬盘中有一个工作表,其中包含一些很酷的参考数据。账户 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 支持的表与原生 BQ 表之间是否存在性能差异?

【问题讨论】:

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


    【解决方案1】:

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

    开始之前:

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

      • https://www.googleapis.com/auth/bigquery
      • https://www.googleapis.com/auth/drive

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

    这是一个对我有用的完整代码 sn-p:

    #!/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()
    

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

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

    【讨论】:

    • 感谢@Juve 的详细描述。我在 Java 中有类似的场景 - 您是否有在 BigQuery API for java 中配置凭据/范围的经验?我的问题 [stackoverflow.com/questions/52202329/…
    • 不,抱歉。另请注意,我的回答可能已过时,因为 Google 可能会添加新功能并修复此类问题;总是仔细检查最新的文档。此外,一般来说,最好寻求没有 DwD 的解决方案,因为它允许模拟 GSuite 中的任何用户。如果您找到不需要 DwD 的解决方案,请留下另一条评论。谢谢!
    【解决方案2】:

    您应该可以通过以下步骤来完成这项工作:

    首先使用与服务帐户关联的电子邮件/“服务帐户 ID”共享工作表。

    然后,如果您使用 bigquery 和 drive 范围创建客户端,您将能够访问您的工作表支持的表。 (您可能需要在服务帐户上启用域范围的委派)。

    scopes = ['https://www.googleapis.com/auth/bigquery', 'https://www.googleapis.com/auth/drive']
    
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
    '<path_to_json>', scopes=scopes)
    
    # Instantiates a client
    client = bigquery.Client(project = PROJECT, credentials = credentials)
    
    bqQuery = client.run_sync_query(q)
    bqQuery.run()
    bqQuery.fetch_data()
    

    【讨论】:

    • 太棒了,谢谢。作为参考,我不必启用域范围委派(无论如何都不确定它是什么),如果您共享文件所在的驱动器文件夹(即使您没有专门共享文件),这也有效,并且 *您必须在帐户 A 的云平台项目中启用 Google Drive API。最后一部分是关键。
    【解决方案3】:

    对于那些尝试通过 Airflow 或 Google Cloud Composer 执行此操作的人,您需要执行两个主要步骤来完成此操作。

    1. 将电子表格的查看权限授予project_name@developer.gserviceaccount.com。这应该与您用于访问 Google BigQuery 的服务帐户相同。这可以在表格 GUI 中或以编程方式完成。

    2. 在 Airflow 中将以下范围添加到您的 Google Cloud Connection:

    然后,您将能够查询引用 Google 表格的外部表。

    【讨论】:

      【解决方案4】:

      只需要从 Evan Kaeding 答案中添加步骤。您可以在 Airflow UI 菜单“管理”->“连接”-> 选择您的连接中找到气流连接。在我的情况下,我还需要在气流连接中添加服务帐户的密钥文件路径或密钥文件 JSON

      基于此引用https://cloud.google.com/composer/docs/how-to/managing/connections#creating_a_connection_to_another_project

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-01
        • 2017-03-20
        • 1970-01-01
        • 2020-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多