Eu tenho JSON
em um arquivo da seguinte forma:
[xyz@innolx20122 ~]$ cat cgs_test.json
{"technology":"AAA","vendor":"XXX","name":"RBNI","temporal_unit":"hour","regional_unit":"cell","dataset_metadata":"{\"name\": \"RBNI\", \"temporal_unit\": \"hour\", \"technology\": \"LTE\", \"is_dimension\": false, \"timestamp_column_pattern\": \"yyyyMMddHHmmss\", \"data_type\": \"PM\", \"source_name\": \"RBNI\", \"intervals_epoch_seconds\": [[1609941600, 1609945200]], \"identifier_column_names\": [\"CELLID\", \"CELLNAME\", \"radio_frequency_band\", \"ENODEBID\", \"ENODEBNAME\", \"SBNID\", \"SITEID\", \"SITENAME\", \"CLUSTER_PRIORITY\", \"CP_SITE\", \"IBC\", \"NETWORK_TIER\", \"SITE_TYPE\", \"T3_FLAG\", \"CLUSTERID\", \"CLUSTERNAME\", \"REGION\", \"NETWORK\"], \"vendor\": \"ZTE\", \"timestamp_column_name\": \"COLLECTTIME\", \"regional_unit\": \"cell\"}","rk":1}
{"technology":"AAA","vendor":"XXX","name":"RRCADD","temporal_unit":"hour","regional_unit":"cell","dataset_metadata":"{\"name\": \"RRCADD\", \"temporal_unit\": \"hour\", \"technology\": \"AAA\", \"is_dimension\": false, \"timestamp_column_pattern\": \"yyyyMMddHHmmss\", \"data_type\": \"PM\", \"source_name\": \"RRCADD\", \"intervals_epoch_seconds\": [[1609941600, 1609945200]], \"identifier_column_names\": [\"CELLID\", \"CELLNAME\", \"radio_frequency_band\", \"ENODEBID\", \"ENODEBNAME\", \"SBNID\", \"SITEID\", \"SITENAME\", \"CLUSTER_PRIORITY\", \"CP_SITE\", \"IBC\", \"NETWORK_TIER\", \"SITE_TYPE\", \"T3_FLAG\", \"CLUSTERID\", \"CLUSTERNAME\", \"REGION\", \"NETWORK\"], \"vendor\": \"XXX\", \"timestamp_column_name\": \"COLLECTTIME\", \"regional_unit\": \"cell\"}","rk":1}
e eu carreguei isso para uma tabela temporária:
create table temp_json (values text);
\copy temp_json from '/home/xyz/cgs_test.json';
Agora eu quero extrair esses dados em colunas separadas como:
technology
vendor
name
temporal_unit
regional_unit
dataset_metadata
rk
dataset_metadata
é uma coluna JSON e outras colunas são strings.
Para responder a esta pergunta o que eu fiz foi o seguinte (veja violino aqui ):
Esta foi uma experiência de aprendizado para mim (+1 para esse BTW), então vou seguir as etapas da minha lógica e espero que isso ajude você - mas estou fazendo isso por mim mesmo :-)
Passo 1:
Passo 2:
Preencha-o com seus dois registros. No entanto, seus dois registros não são JSON apropriados - eles precisam de um
[
no início e]
no final para que sejam JSON apropriados - então, eu os coloqueiINSERT
no início do processo - deixo-o cabe ao leitor experimentar o que acontece se você os deixar de fora - você pode colocá-los mais tarde no processo - veja abaixo.Pode haver uma maneira de não ter que fazer isso com uma
JSON
função diferente - além da minha nota salarial, temo - mas gostaria de receber sugestões de melhorias.Em seguida, transforme as strings em JSON da seguinte maneira - isso pode ser feito em massa:
Etapa 3:
Crie outra tabela:
Passo 4:
Preencha isso por:
O
::JSON
cast é necessário, caso contrário o castINSERT
irá falhar comojson_input
é do tipoTEXT
.Em seguida, limpe `temp_1':
Etapa 5:
Crie uma tabela para armazenar os dados:
Etapa 6:
A partir daqui , obtive este método para preencher a tabela:
Há outra maneira mostrada no violino - daqui - YMMV?
Passo 7 - verificação final:
Resultado:
Um par de pensamentos:
Seu
dataset_metadata
campo não parece ser um JSON "adequado" - talvez um adequadoREGEXP_REPLACE
e/ou umCAST
possa estar em ordem? Não conheço o processo pelo qual você obtém seu/home/xyz/cgs_test.json
arquivo - mas pode valer a pena observar como o registro é gerado - idealmente, você deve corrigir quaisquer problemas o mais cedo possível no pipeline.Eu não sei suas circunstâncias exatas, mas você deve considerar cuidadosamente o conselho aqui - você pode querer agrupar seus metadados em uma tabela separada com uma
FOREIGN KEY
conexão com o registro pai?COPY não se destina a preencher cada linha na coluna como está. Ele quebrará alguma formatação de linha na codificação json aninhada.
Em vez de COPY, você pode usar
pg_read_file
a função admin para ler o arquivo e depois dividir este texto por linha:Então, vemos que o JSON está correto. Vamos reformatar conforme necessário:
Você também pode converter JSON aninhado em dataset_metadata para o tipo de dados JSON e processá-lo ainda mais como desejar. Por exemplo,