将 Biquery 查询格式化为 ML 适当的 JSON 以通过 ML Predict
Posted
技术标签:
【中文标题】将 Biquery 查询格式化为 ML 适当的 JSON 以通过 ML Predict【英文标题】:Formatting Biquery query to ML appropriate JSON to Pass through ML Predict 【发布时间】:2018-04-25 18:33:00 【问题描述】:使用 Python 2.7,我不会将查询从 BigQuery 传递到具有 specific formating 请求的 ML Predict。
首先:有没有一种更简单的方法可以直接从 BigQuery 查询以正确格式转到 JSON,以便可以将其传递给 requests.post()
而不是通过 pandas(据我所知,GCP 标准仍然不支持 pandas )?
第二:有没有办法构造查询以直接转为 JSON 格式,然后修改 JSON 以反映 ML Predict JSON 要求?
目前我的代码如下所示:
#I used the bigquery to dataframe option here to view the output.
#I would like to not use pandas in the end code.
logs = log_data.execute(output_options=bq.QueryOutput.dataframe()).result()
data = logs.to_json(orient='index')
print data
'"0":"end_time":"2018-04-19","device":"iPad","device_os":"ios","device_os_version":"5.1.1","latency":0.150959,"megacycles":140.0,"cost":"1.3075e-08","device_brand":"Apple","device_family":"iPad","browser_version":"5.1","app":"567","ua_parse":"0"'
#The JSON needs to be in this format according to google documentation.
#data =
# 'instances': [
#
# 'key':'',
# 'end_time': '2018-04-19',
# 'device': 'iPad',
# 'device_os': 'iOS',
# 'device_os_version': '5.1.1',
# 'latency': 0.150959,
# 'megacycles':140.0,
# 'cost':'1.3075e-08',
# 'device_brand':'Apple',
# 'device_family':'iPad',
# 'browser_version':'5.1',
# 'app':'567',
# 'ua_parse':'40.9.8'
#
# ]
#
所以我只需要更改前导键 '0'
到 'instances'
并且我应该准备好传递到 `requests.post()。
有没有办法做到这一点?
编辑-添加 BigQuery 查询:
%%bq query --n log_data
WITH `my.table` AS (
SELECT ARRAY<STRUCT<end_time STRING, device STRING, device_os STRING, device_os_version STRING, latency FLOAT64, megacycles FLOAT64,
cost STRING, device_brand STRING, device_family STRING, browser_version STRING, app STRING, ua_parse STRING>>[] instances
)
SELECT TO_JSON_STRING(t)
FROM `my.table` AS t
WHERE end_time >='2018-04-19'
LIMIT 1
data = log_data.execute().result()
感谢@MikhailBerlyant,我已将查询和代码调整为如下所示:
%%bq query --n log_data
SELECT [TO_JSON_STRING(t)] AS instance
FROM `yourproject.yourdataset.yourtable` AS t
WHERE end_time >='2018-04-19'
LIMIT 1
但是当我运行执行 logs = log_data.execute().result()
我得到这个
当传入request.post
时会导致这个错误
TypeError: QueryResultsTable job_zfVEiPdf2W6msBlT6bBLgMusF49E is not JSON serializable
execut() 中有没有办法只返回 json?
【问题讨论】:
【参考方案1】:首先:有没有更简单的方法可以直接从 BigQuery 查询以正确格式转到 JSON
见下例
#standardSQL
WITH yourTable AS (
SELECT ARRAY<STRUCT<id INT64, type STRING>>[(1, 'abc'), (2, 'xyz')] instances
)
SELECT TO_JSON_STRING(t)
FROM yourTable t
结果是您要求的格式:
"instances":["id":1,"type":"abc","id":2,"type":"xyz"]
以上演示了查询及其工作原理 在你的真实情况下 - 你应该使用类似下面的东西
SELECT TO_JSON_STRING(t)
FROM `yourproject.yourdataset.yourtable` AS t
WHERE end_time >='2018-04-19'
LIMIT 1
希望这会有所帮助:o)
基于cmets更新
SELECT [TO_JSON_STRING(t)] AS instance
FROM `yourproject.yourdataset.yourtable` t
WHERE end_time >='2018-04-19'
LIMIT 1
【讨论】:
我已将我的查询添加到问题中。这看起来正确吗?我收到此错误Exception: invalidQuery: Unrecognized name: end_time at [7:7]
您完全丢失了 my.table 中的数据 - 我只看到架构。而不是这个 - 看起来正确。但您需要添加数据。更好 - 只需使用您的真实表并完全删除整个 WIT Hstatement。我需要它只是为了展示方法。有道理吗?
对不起,我可能会混淆。在查询完成之前,我不会知道数据是什么样的。我最终将使它成为一个函数,用户将选择日期并将其传递给查询,因此我将不知道数据是什么。我可以只使用空括号[]
吗?
完全正确,所以你应该使用类似 - SELECT TO_JSON_STRING(t) FROM fourtopapp.daily_logs.app_logs_data_cleaned_20180419_131416
AS t WHERE end_time >='2018-04-19' LIMIT 1
你不需要定义模式 - 并明确设置数据 - 正如我所说 -0 我这样做只是为了演示查询将如何工作【参考方案2】:
我想添加这个,以防有人遇到与我相同的问题,或者至少在你有查询后坚持下去。
我能够编写一个函数,以 Google ML Predict 希望将其传递到 requests.post() 的方式格式化查询。这很可能是实现此目的的一种可怕方法,但我找不到以正确格式从 BigQuery 直接转到 ML Predict 的方法。
def logs(query):
client = gcb.Client()
query_job = client.query(query)
CSV_COLUMNS ='end_time,device,device_os,device_os_version,latency,megacycles,cost,device_brand,device_family,browser_version,app,ua_parse'.split(',')
for row in query_job.result():
var = list(row)
l1 = dict(zip(CSV_COLUMNS,var))
l1.update('key':'')
l2 = 'instances':[l1]
return l2
【讨论】:
以上是关于将 Biquery 查询格式化为 ML 适当的 JSON 以通过 ML Predict的主要内容,如果未能解决你的问题,请参考以下文章