如何在 bigquery 中转储具有未知内容的 json?

Posted

技术标签:

【中文标题】如何在 bigquery 中转储具有未知内容的 json?【英文标题】:How to dump a json with unknown contents in bigquery? 【发布时间】:2019-12-12 13:57:24 【问题描述】:

我想在大查询中插入一个 json 字段。典型的 json 是来自我们网页上所有不同 API 请求的请求负载。因此,典型的 json 可以具有不同的结构和大小。因此,我无法决定将 json 的模式作为大查询中的记录字段插入。两个这样的 json 的例子是:

JSON1 = 
"key": "abcd",
"user_id": "1234FGH",
"start": 5,
"end": 10

JSON2 = 
"key": "efgh",
"creator_id": "789HIJ",
"content_id": "5678XYZ",
"from": 5,
"size": 10

很明显,这些 json 在结构上是不同的。我有来自数百个 API 的有效负载,每个 API 在其请求 json 中都有数百个字段,因此我无法为 BigQuery 中的 Record 字段创建架构。

这是我的python代码:

import os

from google.cloud import bigquery

BIG_Q_CREDENTIALS = os.environ.get("GOOGLE_BIGQ_CREDENTIALS")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = BIG_Q_CREDENTIALS

TABLE_ID = os.environ.get("BIGQ_TABLE_ID")
DATASET_ID = os.environ.get("BIGQ_DATASET_ID")

bigquery_client = bigquery.Client()
dataset_ref = bigquery_client.dataset(DATASET_ID)
table_ref = dataset_ref.table(TABLE_ID)

try:
    table = bigquery_client.get_table(table_ref)
except Exception as e:
    schema = [
                bigquery.SchemaField("event_name", "STRING", mode="REQUIRED"),
                bigquery.SchemaField("uuid", "STRING", mode="REQUIRED"),
                bigquery.SchemaField("request_payload", "RECORD", mode="NULLABLE"),
                bigquery.SchemaField("createdtime", "TIMESTAMP", mode="REQUIRED"),
            ]
    table = bigquery.Table(table_ref, schema=schema)
    table = bigquery_client.create_table(table)

代码错误:

google.api_core.exceptions.BadRequest: 400 POST https://bigquery.googleapis.com/bigquery/v2/projects/PROJECT_ID/datasets/DATASET_NAME/tables: Field request_payload is type RECORD but has no schema

我应该将此有效负载转储为字符串吗?但我担心的是查询它在经济上会很昂贵。

任何帮助将不胜感激。如果您需要我提供的任何东西来帮助我解决这个问题,请告诉我。

【问题讨论】:

这能回答你的问题吗? Bigquery python SchemaField() with ARRAY of STRUCTS 【参考方案1】:

因此,我无法决定将 JSON 作为模式插入 Big Query 中的 RECORD 字段。

这是可以理解的。 JSON 的常见用例是灵活。

RECORD is like a Struct,所以你需要预先指定字段,每个字段都有一个类型(必需)和字段名称(可选)。这就是为什么你应该使用 STRING 来代替:bigquery.SchemaField("request_payload", "STRING", mode="NULLABLE"),并且无论何时你想从你的有效负载中读取,你都可以使用 JSON_EXTRACT 并获得你喜欢的字段。

例如,您将通过运行以下查询获取 user_id:

SELECT *, JSON_EXTRACT(request_payload, "$.user_id") FROM `Project.Dataset.Table`

【讨论】:

以上是关于如何在 bigquery 中转储具有未知内容的 json?的主要内容,如果未能解决你的问题,请参考以下文章

从 appengine 上传到 bigquery 时如何忽略未知值

Google Bigquery 的 Apps 脚本未知错误

`TFRecord` 从 Google BigQuery 转储到 Google Cloud Storage

将 bigquery JSON 数据转储加载到 R tibble

TypeError:无法将值''视为常量,因为它具有未知的类型'function'

将 Azure 存储表转储到未知表模型上