通过 Python API 客户端发送到 BigQuery 时验证查询出现语法错误
Syntax Error with Validated Query when sent into BigQuery via Python API Client
这是我的查询:
SELECT hits.page.pagePath
FROM [(project_id):(dataset_id).ga_sessions_20151019]
GROUP BY hits.page.pagePath LIMIT 1
它 运行 在网络上 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() 函数。谢谢!
我看到您在查询请求中将 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
这是我的查询:
SELECT hits.page.pagePath
FROM [(project_id):(dataset_id).ga_sessions_20151019]
GROUP BY hits.page.pagePath LIMIT 1
它 运行 在网络上 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() 函数。谢谢!
我看到您在查询请求中将 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