如何根据用户输入参数从 BigQuery 获取结果
Posted
技术标签:
【中文标题】如何根据用户输入参数从 BigQuery 获取结果【英文标题】:How to get result from BigQuery based on user input parameters 【发布时间】:2020-08-27 04:18:46 【问题描述】:这是我之前的帖子的延续,用于制作带有 url 参数的 api,将其传递给 BigQuery,如果 luid 记录在 orderid 列中有数据,则返回 True 。 How to check whether data exists in specific column on BigQuery with Flask?
我更改了 sql,似乎这个 sql 在 GCP 控制台上运行良好,但如您所见,如果您从浏览器输入正确的参数,它会返回 Flase('f0_': 0))。我需要修复这个 sql 吗??
[URL:https://test-989898.df.r.appspot.com?luid=U77777]
The output of return str(row)
↓
Row((True,), 'f0_': 0)
The output of SQL with same luid above on console
↓
row | f0_
1 | true
SELECT EXISTS(SELECT 1
FROM `test-266110.conversion_log.conversion_log_2020*` as p
WHERE luid = "U77777" AND orderid != '' limit 1000)
我尝试了这篇文章,如下所示。用户输入参数在 BigQuery 中不可用?? https://cloud.google.com/bigquery/docs/parameterized-queries
@app.route('/')
def get_request():
luid = request.args.get('luid') or ''
client = bigquery.Client()
query = """SELECT EXISTS(SELECT 1
FROM `test-266110.conversion_log.conversion_log_2020*` as p
WHERE @luid = p.luid AND orderid != '' limit 1000)"""
job_config = bigquery.QueryJobConfig(
query_parameters=[
bigquery.ScalarQueryParameter("luid", "STRING", luid),
]
)
query_job = client.query(query, job_config=job_config)
query_res = query_job.result()
for row in query_res:
return str(row)
↓
Row((True,), 'f0_': 0)
我在这个问题上已经有一段时间了,欢迎提出任何想法。谁有好的解决方案??
from flask import Flask, request, jsonify
from google.cloud import bigquery
app = Flask(__name__)
@app.route('/')
def get_request():
luid = request.args.get('luid') or ''
client = bigquery.Client()
query = """SELECT EXISTS(SELECT 1
FROM `test-266110.conversion_log.conversion_log_2020*` as p
WHERE @luid = p.luid AND orderid != '' limit 1000)"""
job_config = bigquery.QueryJobConfig(
query_parameters=[
bigquery.ScalarQueryParameter("luid", "STRING", luid),
]
)
query_job = client.query(query, job_config=job_config)
query_res = query_job.result()
# first_row = next(iter(query_job.result()))
for row in query_res:
return str(row)
#return jsonify(luid:query_res.total_rows)
"""
if query_res == :
return jsonify(luid: str(True))
else:
return jsonify(luid: str(False))
"""
if __name__ == "__main__":
app.run()
↓
Row((True,), 'f0_': 0)
【问题讨论】:
【参考方案1】:您似乎已经解决了大部分问题,这只是让它们一起工作的问题。下面是一个可以帮助解决 BigQuery 问题的快速示例,并展示了使用公共数据集表编写查询模式的不同方式。
from google.cloud import bigquery
client = bigquery.Client()
# assume you get this from your flask app's param. this is the "luid" you're checking.
value = "treason"
# rewriting the sql demonstrate a similar thing with a public dataset table
sql = "SELECT COUNTIF(word=@luid AND corpus='sonnets') > 0 as word_is_sonnet FROM `bigquery-public-data.samples.shakespeare`"
config = bigquery.QueryJobConfig(
query_parameters=[
bigquery.ScalarQueryParameter("luid", "STRING", value),
]
)
job = client.query(sql, job_config=config)
# this is a bit odd, but in this case we know we're dealing with a single row
# coming from the iterable based on the query structure.
first_row = next(iter(job.result()))
print(first_row.get("word_is_sonnet"))
不过,我要确保您了解 BigQuery 的工作原理和查询费用。您似乎正在对一系列表(原始查询中的通配符表)进行点查找,这意味着您可能会进行大量表扫描以满足此请求。
我只是想指出这一点,因此如果您的意图是发出许多这样的请求,您不会对性能或成本感到惊讶。
【讨论】:
非常感谢。我想确认这个重写 sql 只是示例,所以不能按我的预期工作,对吧?? 是的,在公共数据集表上演示更容易。 我明白了。谢谢你。我通过检查 GCP 控制台上的 SQL 执行历史记录找到了问题的原因。我的 sql 中的变量似乎没有传输到 BigQuery,所以我需要寻找在我的 sql 上设置动态变量的方法。以上是关于如何根据用户输入参数从 BigQuery 获取结果的主要内容,如果未能解决你的问题,请参考以下文章
如何从 BigQuery 中的 Firebase 事件中获取用户表?
如何安全地为 bigquery 节点插入转义用户输入?可以在 bigquery.insert 节点库上使用参数化查询吗?