sqlpostgresqljsonjsonb

jsonb_pretty no PostgreSQL: saida JSONB legivel

Como formatar JSONB com indentacao usando jsonb_pretty para depurar no psql e quando nao usar.

3 min de leituraReferencesql · postgresql · json · jsonb · debugging

jsonb_pretty formata um valor JSONB com indentacao e quebras de linha, transformando um documento denso de uma linha em texto legivel. E uma ferramenta para o olho humano: depurar no psql, revisar dados e logs, nao para armazenar ou transportar.

Uso basico

A funcao recebe um unico valor jsonb e retorna text com indentacao de dois espacos por nivel de aninhamento. Compare a forma compacta e a expandida do mesmo documento.

SELECT jsonb_pretty('{"name":"Ana","country":"ES","roles":["admin","ops"]}');

A saida se espalha em linhas e e facil de ler de relance:

{
    "name": "Ana",
    "roles": [
        "admin",
        "ops"
    ],
    "country": "ES"
}

Repare que country aparece depois de roles. O JSONB nao mantem a ordem original das chaves, o que veremos a seguir.

Inspecionar documentos reais

Suponha que users tenha uma coluna profile jsonb com configuracoes e metadados. Sem formatacao, uma linha no psql parece um paredao de texto. Com jsonb_pretty, cada chave fica em sua propria linha.

SELECT u.id, jsonb_pretty(u.profile) AS profile
FROM users u
WHERE u.country = 'ES'
ORDER BY u.created_at DESC
LIMIT 5;

Ele brilha ao conferir agregados. Monte os pedidos de um usuario em um unico documento e olhe diretamente para ele:

SELECT jsonb_pretty(
  jsonb_agg(
    jsonb_build_object(
      'order_id', o.id,
      'amount', o.amount,
      'status', o.status
    ) ORDER BY o.created_at
  )
) AS orders
FROM orders o
WHERE o.user_id = 42;

Assim fica facil confirmar que a agregacao e o jsonb_build_object produzem exatamente a estrutura que voce espera antes de entrega-la a uma aplicacao.

Ordenacao de chaves e normalizacao

Ao fazer o parsing, o JSONB descarta espacos e chaves duplicadas (a ultima vence) e nao preserva a ordem. Internamente as chaves sao armazenadas ordenadas primeiro por comprimento e, em caso de empate, por valor de byte. O jsonb_pretty as imprime nessa mesma ordem interna, sem reordenar nada por conta propria, entao a saida as vezes surpreende.

SELECT jsonb_pretty('{"z":1,"a":2,"aa":3}');

Aqui e facil errar. Por comprimento, as chaves de um caractere a e z vem antes da de dois caracteres aa. Dentro do comprimento 1, o desempate nao e decidido pelo alfabeto em si, mas pelo valor de byte: a e o codigo 0x61 e z e o codigo 0x7a, portanto a vem antes de z. A ordem de saida e, assim, a, z, aa, e nao z, a, aa como voce poderia supor lendo as chaves da esquerda para a direita. Para letras ASCII minusculas a ordem de bytes coincide com o alfabeto, mas assim que aparecem digitos, maiusculas ou caracteres nao ASCII essa intuicao quebra e e preciso raciocinar pelos codigos reais dos caracteres.

Essa propriedade nao e obvia, mas e muito util: estabiliza os diffs. Dois documentos logicamente iguais geram uma saida formatada identica byte a byte, independentemente da ordem de escrita, o que ajuda ao comparar o JSON esperado com o real em testes por meio de um diff de texto puro. Se voce realmente precisar da ordem original das chaves, o JSONB nunca a devolvera: para isso existe o tipo json (sem o b), que guarda o texto exatamente como chegou, mas paga um custo de reparsing a cada acesso.

Quando nao usar

O erro classico e arrastar o jsonb_pretty para o caminho de dados de producao.

  • Armazenamento. Nunca grave o resultado de jsonb_pretty de volta em uma coluna. O JSONB ja e binario; a indentacao e text, bytes extras e um tipo perdido. Guarde jsonb compacto.
  • Transporte. Para APIs e filas, emita row_to_json ou um ::text compacto. A indentacao incha o payload e o cliente nao precisa dela.
  • Desempenho. Ele formata por linha. Nao envolva com ele varreduras pesadas de milhoes de linhas, apenas depuracao pontual com LIMIT.

Pegadinha: o resultado e text, nao jsonb. Se voce aplicar jsonb_pretty e depois tentar filtrar com ->> ou @>, a expressao falha com um erro de tipo. Filtre primeiro sobre jsonb e formate no final, somente para exibicao.

Diferencas em outros bancos

  • MySQL. Sem um nome identico, mas JSON_PRETTY(doc) e a funcao embutida que faz o mesmo trabalho para o tipo JSON.
  • ClickHouse. Analitica orientada a colunas sem uma funcao pretty por expressao para JSON; para uma saida legivel voce escolhe um formato de saida do cliente (por exemplo FORMAT PrettyJSONEachRow) em vez de uma funcao na projecao.

Resumindo: jsonb_pretty e uma conveniencia para o desenvolvedor. Use-o em um SELECT durante a depuracao manual no psql e em relatorios, mas mantenha compactos os dados em suas colunas e canais.

Pratique com exercícios reais

Resolva exercícios no treinador de SQL com correção instantânea e dicas.

Abrir o treinador