【问题标题】:Generate schema from json file using jq使用 jq 从 json 文件生成模式
【发布时间】:2020-07-11 07:47:50
【问题描述】:

我有一个以换行符分隔的 JSON 文件。是否可以使用jq 之类的工具生成模式?我过去在jq 上取得了一些成功,但还没有做过这么复杂的事情。

这是我的目标架构格式:https://cloud.google.com/bigquery/docs/nested-repeated#example_schema。请注意,嵌套使用父级的fields 键处理,数组使用"mode": "repeated" 处理。 (非常感谢对 some 类型架构的任何帮助,然后我可以按摩到这种格式。

从上面的链接复制,我想从中生成:

{"id":"1","first_name":"John","last_name":"Doe","dob":"1968-01-22","addresses":[{"status":"current","address":"123 First Avenue","city":"Seattle","state":"WA","zip":"11111","numberOfYears":"1"},{"status":"previous","address":"456 Main Street","city":"Portland","state":"OR","zip":"22222","numberOfYears":"5"}]}

...到...

[
    {
        "name": "id",
        "type": "STRING",
        "mode": "NULLABLE"
    },
    {
        "name": "first_name",
        "type": "STRING",
        "mode": "NULLABLE"
    },
    {
        "name": "last_name",
        "type": "STRING",
        "mode": "NULLABLE"
    },
    {
        "name": "dob",
        "type": "DATE",
        "mode": "NULLABLE"
    },
    {
        "name": "addresses",
        "type": "RECORD",
        "mode": "REPEATED",
        "fields": [
            {
                "name": "status",
                "type": "STRING",
                "mode": "NULLABLE"
            },
            {
                "name": "address",
                "type": "STRING",
                "mode": "NULLABLE"
            },
            {
                "name": "city",
                "type": "STRING",
                "mode": "NULLABLE"
            },
            {
                "name": "state",
                "type": "STRING",
                "mode": "NULLABLE"
            },
            {
                "name": "zip",
                "type": "STRING",
                "mode": "NULLABLE"
            },
            {
                "name": "numberOfYears",
                "type": "STRING",
                "mode": "NULLABLE"
            }
        ]
    }

]

(参考 BigQuery autodetect doesn't work with inconsistent json?,表明我不能使用 BigQuery 自动检测,因为项目不一样。我很有信心可以手动将架构合并在一起以创建超集)

【问题讨论】:

    标签: json schema jq


    【解决方案1】:

    非常感谢任何有关某种模式的帮助,然后我可以按摩成这种格式

    http://gist.github.com/pkoppstein/a5abb4ebef3b0f72a6ed 有一个用 jq 编写的模式推断模块,但推断的模式是“结构化的”——它们反映了输入 JSON。对于您的示例,推断的架构如下所示。如您所见,将其转换为您想要的格式非常容易,除了需要额外的工作来推断 mode 值。

    请注意,上述模块从任意大的 JSON 文档“样本”中推断出“通用模式”。也就是说,它是一个模式推理引擎,而不是简单的“模式生成器”。

    上面的链接引用了一个名为 JESS 的配套模式检查器,它也是用 jq 编写的。 “JESS”中的“E”代表“扩展”,表示用于指定模式的 JESS 模式语言允许包含复杂的约束。

    {
      "id": "string",
      "first_name": "string",
      "last_name": "string",
      "dob": "string",
      "addresses": [
        {
          "status": "string",
          "address": "string",
          "city": "string",
          "state": "string",
          "zip": "string",
          "numberOfYears": "string"
        }
      ]
    }
    

    【讨论】:

      【解决方案2】:

      这是一个简单的递归函数,如果您决定自己动手,它可能会有所帮助:

      def schema:
        def isdate($v):   $v | test("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]");
        def array($k;$v): {"name":$k,"type":"RECORD",mode:"REPEATED","fields":($v[0] | schema)};
        def date($k):     {"name":$k,"type":"DATE",  mode:"NULLABLE"};
        def string($k):   {"name":$k,"type":"STRING",mode:"NULLABLE"};
        def item($k;$v):
           $v | if   type == "array"                 then array($k;$v)
                elif type == "string" and isdate($v) then date($k)
                elif type == "string"                then string($k)
            else empty end;
        [ to_entries[] | item(.key;.value) ]
      ;
      schema
      

      Try it online!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-24
        • 2019-05-11
        • 2017-02-22
        • 2015-01-19
        • 2019-07-19
        • 2019-06-23
        • 2018-06-30
        • 1970-01-01
        相关资源
        最近更新 更多