Google sheets 如何对服务帐户进行身份验证,以便对GDrive Sheet支持的BigQuery表进行查询?

Google sheets 如何对服务帐户进行身份验证,以便对GDrive Sheet支持的BigQuery表进行查询?,google-sheets,google-bigquery,google-cloud-platform,google-spreadsheet-api,Google Sheets,Google Bigquery,Google Cloud Platform,Google Spreadsheet Api,我的情况如下: Google帐户A在BigQuery中有一些数据 Google帐户B管理帐户A的BigQuery数据,并且还被授予帐户A的云平台项目的编辑权限 帐户B在Google Drive中有一张表格,里面有一些很酷的参考数据。帐户B登录到BQ Web控制台,并在帐户a的BQ项目中创建一个表,该表由该表支持 一切都很好。帐户B可以从web UI在帐户A的BQ数据内成功查询并加入此表 问题: Google帐户A还有一个服务帐户,是Google帐户A的云平台项目的编辑器。此服务帐户使用pytho

我的情况如下:

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

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

帐户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表支持的表与本机BQ表之间是否存在性能差异?

您应该能够通过以下步骤实现这一点:

首先使用与服务帐户关联的电子邮件/“服务帐户id”共享该表

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()
然后,若您创建了一个具有bigquery和驱动器作用域的客户机,那个么您就可以访问表备份表了。(您可能需要在服务帐户上启用域范围的委派)

scopes=['https://www.googleapis.com/auth/bigquery', 'https://www.googleapis.com/auth/drive']
credentials=ServiceAccountCredentials.from_json_keyfile_name(
'',范围=范围)
#实例化客户机
client=bigquery.client(项目=项目,凭证=凭证)
bqQuery=客户端。运行同步查询(q)
bqQuery.run()
bqQuery.fetch_data()

当轨道的回答帮助我找到解决问题的方法时,还有一些事情需要考虑。因此,我想补充我对这个问题的详细解决办法。如果Orbit的基本解决方案不起作用,特别是如果您使用并且您的策略不允许与域外的帐户共享工作表/文档,则需要此解决方案。在这种情况下,您不能直接与服务帐户共享单据/工作表

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()
在开始之前:

  • 在项目中创建或选择
  • 在中启用域范围的委派()。如果不存在,则为服务帐户生成OAuth客户端ID
  • 确保委托的
    user@company.com
    可以访问该工作表
  • 向服务帐户的OAuth客户端添加所需的作用域(您可能需要请求G套件管理员为您执行此操作):

    • 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()
    
    请注意,我无法直接设置委派,需要使用
    creds=creds.create\u delegated(delegated\u user)
    HTTP=creds.authorize(httplib2.HTTP())
    创建HTTP客户机。然后,授权的HTTP客户端可以用作BigQuery客户端的HTTP客户端:
    client=BigQuery.client(HTTP=HTTP)


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

    对于那些试图通过Airflow或Google Cloud Composer实现这一点的人,您需要完成两个主要步骤

  • 授予
    项目对电子表格的查看权限_name@developer.gserviceaccount.com
    。这应该是您用来访问Google BigQuery的同一个服务帐户。这可以在工作表GUI中完成,也可以通过编程实现

  • 在Airflow中将以下范围添加到您的Google云连接:


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

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


    基于这些参考资料

    太棒了,谢谢。作为参考,我不必启用域范围的委派(不确定它到底是什么),如果您共享文件所在的驱动器文件夹(即使您没有专门共享文件),这项功能就可以工作,并且*您必须在帐户a的云平台项目中启用Google drive API。最后一部分是关键。谢谢@尤文的详细描述。我在Java中有一个类似的场景-您有没有在BigQueryAPI for Java中配置凭据/作用域的经验?我的问题[不,抱歉。请注意,我的回答可能已经过时,因为谷歌可能会添加新功能并解决此类问题;请始终仔细检查最新文档。此外,一般来说,最好在没有DwD的情况下寻找解决方案,因为它允许模拟GSuite中的任何用户。如果您找到一个不需要DwD的解决方案,请留下另一个命令新台币,谢谢!