Python BigQuery JSON模式验证

Python BigQuery JSON模式验证,python,json,validation,google-bigquery,Python,Json,Validation,Google Bigquery,是否有任何工具可以根据BigQuery模式验证JSON字符串? 我想把有效的加载到BQ,然后重新处理无效的 我知道您可以使用(例如)python的jsonschema对标准JSON模式进行验证,BQ模式是否也有类似的功能 关于奔腾10的评论,我可以想象许多ETL场景,其中来自多个源的数据必须进行组装,以使其与BQ模式匹配——目前我需要两个数据模式,一个JSON模式和一个BQ模式——我根据JSON模式进行验证,并希望这足以满足提交时的BQ模式 具体地说:在这种情况下,我使用的JSON来自jav

是否有任何工具可以根据BigQuery模式验证JSON字符串? 我想把有效的加载到BQ,然后重新处理无效的

我知道您可以使用(例如)python的jsonschema对标准JSON模式进行验证,BQ模式是否也有类似的功能


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



具体地说:在这种情况下,我使用的JSON来自javascript前端,并作为字符串输入到BQ中。我想处理这个字段,并将其作为一个表添加到BQ中,这样我就可以搜索它了


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

如果您用JSON模式()然后您应该能够使用他们列出的工具之一进行验证。

我建议您在Python中将JSON模式用作JSON对象,这样您可以尝试使用BigQuery的库验证模式

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

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

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

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

您可以尝试格式化BQ JSON模式,以便在此处进行比较:

我知道这不是一个容易实现的解决方案,但我想如果你把它调整得足够好,它将是健壮的,可以解决你的问题。请尽管问我是否能帮你更多


查看有关模式的更多信息

如果没有提供任何示例,很难回答这个问题,但您通常可以使用它

以下是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
模块由软件包提供

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

是否使用JSON或YAML以及如何存储和解析模式取决于您


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

这是我创建的实现之一。


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

这种功能的实际用例场景是什么?我有一个JSON,它来自javascript前端,并作为字符串输入到BQ中。
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)
"$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
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)