100 % local — seus dados nunca saem do seu navegador

JSON para PostgreSQL — cole direto no psql

Transforme uma amostra JSON num CREATE TABLE do PostgreSQL. As strings viram TEXT, o aninhado vira JSONB, e uma chave ausente em linhas fica nullable.

Instantâneo Privado Zero cookies

Entrada JSON

Saída PostgreSQL

O que esta ferramenta faz

Uma amostra JSON vira um CREATE TABLE.

{ "id": 1, "firstName": "Ada", "score": 9.5, "address": { "city": "Paris" } }
CREATE TABLE "root" (
  "id" BIGINT NOT NULL,
  "first_name" TEXT NOT NULL,
  "score" DOUBLE PRECISION NOT NULL,
  "address" JSONB NOT NULL
);

Os nomes vão em snake_case e entre aspas, o que os mantém exatos e deixa uma palavra reservada como "order" ser coluna sem cerimônia.

TEXT não tem comprimento a inventar

O PostgreSQL guarda TEXT e VARCHAR(n) do mesmo jeito; a única diferença é a restrição. Como uma amostra não sabe o limite real — só o valor mais longo que por acaso contém —, nenhum limite é escrito. Acrescentar VARCHAR(40) depois é decisão sobre o seu domínio, e não custa nada em armazenamento.

Por isso esta página também não tem o equivalente da nota do MySQL sobre VARCHAR(255): aqui não há comprimento em que errar.

Todas as linhas, não só a primeira

[{ "a": 1 }, { "b": "x" }]
CREATE TABLE "root_item" (
  "a" BIGINT NULL,
  "b" TEXT NULL
);

A tabela era construída só com o primeiro objeto: a segunda linha da sua própria amostra não tinha para onde ir. Agora as colunas são a união de todos os objetos, e uma chave que falta em algumas linhas é nullable — porque é.

Os tipos se fundem do mesmo jeito. Quando a mesma chave é um número num objeto e uma string noutro, nenhuma coluna escalar aceita os dois: a coluna vira JSONB. Um inteiro ao lado de um decimal é outra coisa — DOUBLE PRECISION cobre ambos, e é o que ele recebe.

JSONB para aquilo que o SQL não tem coluna

Objetos e arrays aninhados viram JSONB. Sem tabela ligada nem chave estrangeira: uma amostra mostra uma forma, nunca uma relação, e inventar uma junção seria adivinhar de uma vez uma tabela, uma chave e um sentido.

JSONB é a forma consultável — ->, ->>, @>, e um índice GIN quando precisar. O tipo json simples guarda o texto original, o que só importa se você planeja devolver o documento inalterado.

Fazer as linhas entrarem

O PostgreSQL não tem bq load. O COPY é construído em torno de texto linha a linha e de CSV, não de um array de objetos JSON: a tabela acima é só metade do trabalho.

O caminho óbvio é o jsonb_populate_recordset, que casa chaves JSON com nomes de coluna — de forma exata, caractere por caractere. É aí que está a armadilha: a tabela acima renomeou firstName para first_name, então esse caminho deixaria a coluna em NULL sem dizer nada.

O mapeamento que combina com a tabela acima é explícito, e diz qual chave alimenta qual coluna:

INSERT INTO "root" ("id", "first_name", "score", "address")
SELECT (e->>'id')::bigint,
       e->>'firstName',
       (e->>'score')::double precision,
       e->'address'
FROM jsonb_array_elements(:'doc'::jsonb) AS e;

:'doc' é uma variável do psql que carrega o documento — psql -v doc="$(cat data.json)" -f load.sql enquanto o arquivo couber num argumento. Além disso, copie o texto para uma tabela de passagem de uma coluna e selecione dali; a forma da consulta não muda.

O que uma amostra não consegue dizer

  • Sem chave primária. Um id que parece único num documento não promete nada sobre o seguinte.
  • Sem índice, sem valor padrão, sem CHECK. São afirmações sobre o dado, não leituras dele.
  • NOT NULL onde havia valor, NULL para um null e para uma chave ausente em alguns objetos.

Privado por padrão

Tudo é executado localmente no seu navegador com JavaScript. Os seus dados nunca são enviados para um servidor, o que torna a ferramenta segura para conteúdo sensível e funciona offline.

Perguntas frequentes

Por que TEXT e não VARCHAR(n)?
Porque o PostgreSQL guarda os dois igual e o TEXT não tem comprimento a adivinhar. `VARCHAR(n)` acrescenta uma restrição, útil quando o limite é uma regra do seu domínio e uma armadilha quando é só o valor mais longo de uma amostra. Acrescente a restrição quando souber a regra; o armazenamento não muda.
Por que meus identificadores vão entre aspas duplas?
Porque as aspas tornam o nome exato. Sem elas, o PostgreSQL dobra os identificadores para minúsculas: uma coluna ainda funcionaria — até que uma chave peça um caractere que o analisador não aceita. Citar tudo mantém uma regra em vez de duas, e faz de `"order"` ou `"group"` colunas comuns em vez de palavras reservadas.
JSON ou JSONB?
JSONB, porque é o tipo que se indexa e se consulta com eficiência; o `json` simples guarda o texto exato, com ordem de chaves e espaços, o que só importa se você pretende devolver o documento byte a byte. Se for o caso, troque o tipo — nada mais na tabela depende disso.

Conversores relacionados