Создать схему из файла json, используя jq - PullRequest
1 голос
/ 30 марта 2020

У меня есть файл JSON с разделителем новой строки. Можно ли сгенерировать схему с помощью такого инструмента, как jq? У меня был некоторый успех с jq в прошлом, но я не сделал ничего сложного.

Вот формат схемы, к которой я стремлюсь: https://cloud.google.com/bigquery/docs/nested-repeated#example_schema. Обратите внимание, что вложение обрабатывается ключом fields родительского элемента, а массивы обрабатываются с помощью "mode": "repeated". (Любая помощь с некоторыми схемами очень важна, и я затем могу помассировать в этот формат).

Копируя по ссылке выше, я хотел бы сгенерировать из этого:

{"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"}]}

... to ...

[
    {
        "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"
            }
        ]
    }

]

(ref Автоопределение BigQuery не работает с несовместимыми json?, показывая, что я не могу использовать автоопределение BigQuery, потому что элементы не совпадают. Я вполне уверен, что могу объединить схемы вручную для создания надмножества)

Ответы [ 2 ]

2 голосов
/ 31 марта 2020

Вот простая рекурсивная функция, которая может помочь, если вы решите бросить свою собственную:

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

Попробуйте онлайн!

1 голос
/ 31 марта 2020

Любая помощь с какой-либо схемой будет принята с благодарностью, и я смогу перейти в этот формат

. В jq на http://gist.github.com/pkoppstein/a5abb4ebef3b0f72a6ed написан модуль вывода схемы но выведенные схемы являются "структурными" - они отражают входные данные JSON. Для вашего примера выведенная схема выглядит так, как показано ниже. Как вы можете видеть, было бы довольно легко преобразовать это в формат, который вы имеете в виду, за исключением того, что потребовалась бы дополнительная работа, чтобы вывести значения mode.

Обратите внимание, что вышеупомянутый модуль выводит «общую схему» из произвольно большой «выборки» JSON документов. То есть это механизм вывода схемы, а не просто «генератор схемы».

Приведенная выше ссылка ссылается на компаньон-проверку схемы с именем JESS, также написанный на jq. «E» в «JESS» означает «расширенный», что означает, что язык схемы JESS для указания схем допускает включение сложных ограничений.

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