我的情况如下:
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并且您的政策不允许与域外的帐户共享工作表/文档。在这种情况下,您不能直接与服务帐户共享文档/工作表。
在你开始前:
user@company.com
可以访问工作表。 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/