【问题标题】:BigQuery JSON schema validationBigQuery JSON 架构验证
【发布时间】: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 中。

标签: python json validation google-bigquery


【解决方案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 日志中容易出错的字段。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-10-18
          • 1970-01-01
          • 2021-08-03
          • 2020-03-22
          • 2015-09-11
          • 1970-01-01
          • 2018-10-17
          相关资源
          最近更新 更多