【问题标题】:How to query BigQuery programmatically from Python without end-user interaction?如何在没有最终用户交互的情况下从 Python 以编程方式查询 BigQuery?
【发布时间】:2012-10-24 03:51:02
【问题描述】:

这个问题看起来应该很容易回答,但是经过几天的研究和几个死胡同,如果不坚持基于用户的 OAuth,我似乎无法从BigQuery 中获得查询结果。有没有人有这方面的运气?我的应用程序没有使用Google AppEngine,它托管在EC2 中。具体情况如下:

User wants reporting data -->
Web server makes queries to BigQuery -->
Data is transformed for use in WebApp and returned to User.

每当我按照 Google 示例进行操作时,最终都会弹出一个网络浏览器,要求我选择一个用于身份验证的 Google 帐户。

【问题讨论】:

    标签: python google-bigquery


    【解决方案1】:

    抱歉,很难找到相关信息。您正在寻找我们的 Authorizing Access to the BigQuery API using OAuth 2.0 指南中记录的称为 Service Accounts 的内容。

    这是一个使用 Python client library 的示例,但您需要查看参考文档以获取有关获取适当凭据的信息:

    import httplib2
    
    from apiclient.discovery import build
    from oauth2client.client import SignedJwtAssertionCredentials
    
    # REPLACE WITH YOUR Project ID
    PROJECT_NUMBER = 'XXXXXXXXXXX'
    # REPLACE WITH THE SERVICE ACCOUNT EMAIL FROM GOOGLE DEV CONSOLE
    SERVICE_ACCOUNT_EMAIL = 'XXXXX@developer.gserviceaccount.com'
    
    # OBTAIN THE KEY FROM THE GOOGLE APIs CONSOLE
    # More instructions here: http://goo.gl/w0YA0
    f = file('key.p12', 'rb')
    key = f.read()
    f.close()
    
    credentials = SignedJwtAssertionCredentials(
        SERVICE_ACCOUNT_EMAIL,
        key,
        scope='https://www.googleapis.com/auth/bigquery')
    
    http = httplib2.Http()
    http = credentials.authorize(http)
    
    service = build('bigquery', 'v2')
    datasets = service.datasets()
    response = datasets.list(projectId=PROJECT_NUMBER).execute(http)
    
    print 'Dataset list:'
    for dataset in response['datasets']:
      print '%s' % dataset['datasetReference']['datasetId']
    

    【讨论】:

    • 瑞恩,感谢您的回复。这让我更进一步。我之前遇到过服务帐户,很明显这就是我要找的,我只是找不到在哪里设置它。我已经这样做了,并使用正确的 ProjectId、服务帐户电子邮件和密钥文件运行了上面的代码,但是当我获取列出数据集的响应时,字典中没有“数据集”键。相反,它是这样的: {u'kind': u'bigquery#datasetList', u'etag': u'"viowSXH0JIvMREGVicRUeTw4PZo/L-a0Zjajejhksaj6mKpTzCQGsr4"'}
    • 因此,要跟进,请确保您正在调用 service.datasets().list() 方法。在上面的示例中,response['datasets'] 对象将包含数据集描述对象的列表,形式为 {u'kind': u'bigquery#dataset', u'id': u'projectXXXXXXX:TestDataset' , u'datasetReference': {u'projectId': u'projectXXXXXXX', u'datasetId': u'TestDataset'}}
    • 另一件事:如果您的 API 响应中没有数据集,很可能您还没有创建任何数据集。你能确认你在你正在使用的项目中这样做了吗?
    • Ryan 感谢您的回答。文档到处都是。但我很高兴谷歌有人在听
    • 4 年后和同样的问题 - 文档通常假设将使用 Google 服务器。并且建议的 SignedJwtAssertionCredentials 方法不存在。添加了当前对我有用的答案。
    【解决方案2】:

    如果您使用gcloud在本地登录:

    gcloud auth application-default login
    

    然后会在 ~/.config/gcloud/ 中存储一个凭证文件,可以通过以下方式加载:

    from oauth2client.client import GoogleCredentials
    from apiclient.discovery import build
    
    credentials = GoogleCredentials.get_application_default()
    service = build('bigquery', 'v2')
    

    或者您可以直接加载 BQ 安全密钥文件:

    from google.cloud import bigquery
    client = bigquery.Client.from_service_account_json(path_to_key.json)
    

    【讨论】:

    • 感谢您使用最新库的答案。请注意,现在有一个文档页面 cloud.google.com/bigquery/docs/authentication/… 涵盖了这些身份验证方法。
    • 请注意,不再推荐使用gcloud auth application-default login。为服务帐户下载 JSON 密钥文件并设置 GOOGLE_APPLICATION_CREDENTIALS 环境变量是在混合环境中设置凭据的最可靠方法。
    【解决方案3】:

    我有同样的问题。这可能是因为您在项目中没有您正在使用的服务帐户密钥的必要权限。

    【讨论】:

    • 这更像是一个评论而不是一个答案。请考虑以 cmets 的形式发布简短的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多