通过 Python API 客户端将经过验证的查询发送到 BigQuery 时出现语法错误

Posted

技术标签:

【中文标题】通过 Python API 客户端将经过验证的查询发送到 BigQuery 时出现语法错误【英文标题】:Syntax Error with Validated Query when sent into BigQuery via Python API Client 【发布时间】:2016-03-10 20:59:33 【问题描述】:

这是我的查询:

SELECT hits.page.pagePath
FROM [(project_id):(dataset_id).ga_sessions_20151019]
GROUP BY hits.page.pagePath LIMIT 1

它在 Web UI 中运行。

这是我的代码:

from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
from apiclient.discovery import build
import json

query = "SELECT hits.page.pagePath FROM [(project_id):(dataset_id).ga_sessions_20151019] GROUP BY hits.page.pagePath LIMIT 1",

path = (filepath of credentials json file)
scopes = ['https://www.googleapis.com/auth/bigquery']
credentials = ServiceAccountCredentials.from_json_keyfile_name(path,scopes)
http_auth = credentials.authorize(Http())
bigquery = build('bigquery','v2',http=http_auth)

req_body = 
    "timeoutMs": 60000,
    "kind": "bigquery#queryRequest",
    "dryRun": False,
    "useQueryCache": True,
    "useLegacySql": False,
    "maxResults": 100,
    "query": query,
    "preserveNulls": True,
  

bigquery.jobs().query(projectId=(project_id),body=req_body).execute()

当我运行它时,我收到以下错误:

HttpError: <HttpError 400 when requesting https://www.googleapis.com/bigquery/v2/projects/cardinal-path/queries?alt=json returned "Syntax error: Unexpected "["">

它似乎不喜欢我的查询字符串中的括号,但我不知道如何转义它们(如果这是问题的话)。有谁看到我做错了什么?我不认为这是我与 API 的连接的问题,因为我可以通过调用服务对象的 ('bigquery'以上)jobs().list() 函数。谢谢!

【问题讨论】:

您是否尝试过用括号替换查询中的括号?尽管听起来很奇怪,但这可能会解决您的问题。如果这不能解决问题,您可能还想尝试根本不包括括号。看看它是否有效。 我很确定 BigQuery 需要括号才能知道我指的是表。我尝试删除它们并用括号替换它们,结果查询既不会在 Web UI 中运行,也不会通过 API 运行。您认为这可能是编码问题吗? 【参考方案1】:

我看到您在查询请求中将useLegacySql 设置为False

[projectid:datasetid.tableid] 这样的括号引用文字是旧版 BigQuery SQL 方言的一部分。

新的 sql 方言使用反引号来引用文字。所以试试:

SELECT hits.page.pagePath FROM `project_id:dataset_id.ga_sessions_20151019` GROUP BY hits.page.pagePath LIMIT 1

另外,由于您将 project_id 作为您正在运行作业的项目传递,所有数据集查找将默认解析为该项目,因此您可以删除 projectid: 前缀并只使用 datasetid.tableid 像:

SELECT hits.page.pagePath FROM dataset_id.ga_sessions_20151019 GROUP BY hits.page.pagePath LIMIT 1

虽然这对于用户键入的查询很方便,但如果您的所有查询都是代码生成的,那么始终使用带引号的完全限定引用可能是最安全的。

更新:另一种选择是将 SQL 的标准点分隔符与非旧版 SQL 方言一起使用,即

SELECT hits.page.pagePath 
FROM project_id.dataset_id.ga_sessions_20151019
GROUP BY hits.page.pagePath LIMIT 1

【讨论】:

什么是传统方言与新方言?有什么细节吗? 即将推出!关注code.google.com/p/google-bigquery/issues/detail?id=448。

以上是关于通过 Python API 客户端将经过验证的查询发送到 BigQuery 时出现语法错误的主要内容,如果未能解决你的问题,请参考以下文章

执行经过身份验证的 keystone.js / GraphQL API 查询

如何使用python请求将经过身份验证的POST请求编码到API?

通过 JSON 在 Google latitude API 中获取经过身份验证的用户的过去签到

如何从 android 客户端进行经过身份验证的 django rest api 调用?

Google 通过 OAuth2 身份验证从 JavaScript 客户端联系 API 问题

Python API简单验证