BigQuery JSON 架构验证

Posted

技术标签:

【中文标题】BigQuery JSON 架构验证【英文标题】:BigQuery JSON schema validation 【发布时间】:2015-10-23 00:30:00 【问题描述】:

是否有任何工具可以根据 BigQuery 架构验证 JSON 字符串? 我想将有效的加载到BQ,并重新处理无效的。

我知道您可以使用(例如)python 的 jsonschema 来验证标准 JSON 模式,BQ 模式是否有类似的东西?


关于 Pentium10 的评论,我可以想象一些 ETL 场景,其中必须组装来自多个来源的数据以使其匹配 BQ 模式 - 目前我需要 2 个数据模式,一个 JSON 模式和一个 BQ 模式 -我根据 JSON 模式进行验证,并希望这足以满足提交时的 BQ 模式。


具体来说:在这种情况下,我有从 javascript 前端到达的 JSON,并作为字符串输入 BQ。我想处理这个字段,并将其作为表格添加到 BQ 中,以便我可以搜索它。

JSON(或多或少)属于 2 个“模式”,但它的类型很差(即数字被视为字符串,长度为 1 的列表是字符串,而不是列表......)。我想要一个快速的方法来查看一个字段是否会进入表中,我有一个 BQ 表模式似乎有点傻,但无法验证它 - 相反,我还必须为理想化数据创建一个 JSON 模式和必须对此进行检查。

【问题讨论】:

这种功能的真实用例场景是什么? 我有从 javascript 前端到达的 JSON,并作为字符串输入到 BQ 中。 【参考方案1】:

我建议您将 JSON 架构用作 Python 中的 JSON 对象,这样您可以尝试使用 BigQuery 的库来验证架构。

1 - 从 BigQuery 表中请求架构(应随后动态实现):

from google.cloud import bigquery
client = bigquery.Client(project='your_project')
dataset_ref = client.dataset('your_dataset')
table_ref = dataset_ref.table('your_table_name')
table_helper = client.get_table(table_ref)

2 - 获取架构并将其格式化为 JSON,之后您应该能够比较两个架构。

你现在拥有的是一个包含 SchemaField() 的列表

your_schema = table_helper.schema

您可以尝试格式化列表,然后将其转储到 JSON 对象中...

formatted_list_schema = ["'0','1','2',3,4".format(schema.name,schema.field_type,schema.mode,schema.description,schema.fields) for schema in table_helper.schema]

json_bq_schema = json.dumps(formatted_list_schema)

您可以尝试格式化该 BQ-JSON-Schema 以便像他们在此处那样进行比较:How to compare two JSON objects with the same elements in a different order equal?

我知道这不是一个易于实施的解决方案,但我想如果你将它调整得足够好,它会很强大并且可以解决你的问题。随时问我是否可以为您提供更多帮助...

查看有关架构的更多信息https://cloud.google.com/bigquery/docs/schemas

【讨论】:

【参考方案2】:

如果您在 JSON 模式 (http://json-schema.org/implementations.html) 中重新表达您的模式,那么您应该能够使用他们列出的工具之一进行验证。

【讨论】:

【参考方案3】:

如果没有提供任何示例,很难回答,但您通常可以使用jsonschema。

这是 YAML 中的元模式定义:

"$schema": http://json-schema.org/draft-07/schema

title: Metaschema for BigQuery fields definition schemas
description: "See also: https://cloud.google.com/bigquery/docs/schemas"

type: array
minItems: 1
uniqueItems: yes

items:
  "$id": "#/items"
  title: Single field definition schema
  type: object

  examples:

  - name: Item_Name
    type: STRING
    mode: NULLABLE
    description: Name of catalog item

  - name: Item_Category
    type: STRING
    mode: REQUIRED

  - name: Exchange_Rate
    type: NUMERIC

  additionalProperties: no
  required:
  - name
  - type

  properties:

    name:
      "$id": "#/items/properties/name"
      title: Name of field
      description: "See also: https://cloud.google.com/bigquery/docs/schemas#column_names"
      type: string
      minLength: 1
      maxLength: 128
      pattern: "^[a-zA-Z_]+[a-zA-Z0-9_]*$"
      examples:
      - Item_Name
      - Exchange_Rate

    description:
      "$id": "#/items/properties/description"
      title: Description of field
      description: "See also: https://cloud.google.com/bigquery/docs/schemas#column_descriptions"          
      type: string
      maxLength: 1024

    type:
      "$id": "#/items/properties/type"
      title: Name of BigQuery data type
      description: 'See also: https://cloud.google.com/bigquery/docs/schemas#standard_sql_data_types'
      type: string
      enum:
      - INTEGER
      - FLOAT
      - NUMERIC
      - BOOL
      - STRING
      - BYTES
      - DATE
      - DATETIME
      - TIME
      - TIMESTAMP
      - GEOGRAPHY

    mode:
      "$id": "#/items/properties/mode"
      title: Mode of field
      description: 'See also: https://cloud.google.com/bigquery/docs/schemas#modes'
      type: string
      default: NULLABLE
      enum:
      - NULLABLE
      - REQUIRED
      - REPEATED

这是我能够从 GCP 文档生成的最精确的元模式。不过,这里不支持结构和数组。

YAML 在这里只是为了便于阅读,如果需要,您可以轻松地将其转换为 JSON。

假设上面的元模式保存为“/path/to/metaschema.yaml”,用法如下:

import json

from pathlib import Path

import jsonschema
import yaml


metaschema = yaml.safe_load(Path("/path/to/metaschema.yaml").read_text())

schema = """["name": "foo", "type": "STRING"]"""
schema = json.loads(schema)


jsonschema.validate(schema, metaschema)

上面的yaml 模块由PyYAML 包提供。

如果schema 有效,jsonschema.validate() 函数将简单地通过。否则会抛出jsonschema.exceptions.ValidationError,并给出错误解释。

使用 JSON 还是 YAML 以及如何存储和解析模式由您决定。

还取决于您是否将类型和模式的名称转换为大写/小写。

【讨论】:

【参考方案4】:

这是我创建的实现之一。 https://github.com/toshi0607/bq-schema-validator

有点模糊,但通常会检测到 JSON 日志中容易出错的字段。

【讨论】:

以上是关于BigQuery JSON 架构验证的主要内容,如果未能解决你的问题,请参考以下文章

使用 bigquery 中的 bigquery select 语句的 JSON 格式的现有表的架构

BigQuery 中的部分 JSON 架构

JSON 表架构到 bigquery.TableSchema 用于 BigQuerySink

使用 Python 将 BigQuery 架构表转换为 json

Dataproc + BigQuery 示例 - 有可用的吗?

单独 JSON 文件中的 Terraform Bigquery 表架构