PauloRB.dev

Desenvolvedor de Software

Como Atualizar Valores de Chaves em Campos JSON no PostgreSQL | PauloRB.dev Como Atualizar Valores de Chaves em Campos JSON no PostgreSQL – PauloRB.dev
Como Atualizar Valores de Chaves em Campos JSON no PostgreSQL

Como Atualizar Valores de Chaves em Campos JSON no PostgreSQL

Atualizar valores em um campo JSON no PostgreSQL é uma operação comum ao trabalhar com dados semi-estruturados. Isso é especialmente útil em cenários onde armazenamos configurações, respostas de questionários ou qualquer estrutura de dados flexível diretamente no banco de dados. Neste artigo, exploraremos como atualizar valores de um campo do tipo JSON em PostgreSQL, utilizando a função jsonb_set, que é uma das mais eficientes e flexíveis ferramentas para lidar com JSON. Vamos abordar diferentes exemplos e cenários para mostrar como atualizar valores em JSON de maneira dinâmica e otimizada.

Estrutura Básica do JSON no PostgreSQL

Antes de irmos aos exemplos, vale a pena lembrar que o PostgreSQL suporta dois tipos principais para trabalhar com JSON:

  • JSON: É o tipo que armazena o dado sem otimizações de busca e indexação.
  • JSONB: Uma versão binária e mais eficiente, adequada para buscas e atualizações.

Vamos focar no uso de JSONB, que é amplamente recomendado para operações frequentes.

Atualizando Chaves Específicas em um Campo JSON

Imagine que temos uma tabela usuarios com um campo configuracoes que armazena preferências dos usuários no formato JSON. Um exemplo de um valor nesse campo poderia ser:

{
  "tema": "claro",
  "notificacoes": {
    "email": true,
    "sms": false
  },
  "idioma": "pt-BR"
}

Agora, suponha que precisamos alterar o valor da chave tema para "escuro" e a chave sms dentro de notificacoes para true. Para isso, usamos a função jsonb_set do PostgreSQL, que nos permite atualizar valores específicos em um campo JSON.

Exemplo de Atualização Simples:

UPDATE usuarios
SET configuracoes = jsonb_set(configuracoes::jsonb, '{tema}', '"escuro"')
WHERE id = 1;

Nesse exemplo, estamos convertendo o campo configuracoes para JSONB (caso ele seja do tipo JSON) e, em seguida, usando jsonb_set para alterar o valor da chave tema. O PostgreSQL usa o caminho especificado ({tema}) para encontrar o valor que será atualizado.

Agora, vamos atualizar o valor dentro de notificacoes para habilitar as notificações via SMS:

UPDATE usuarios
SET configuracoes = jsonb_set(configuracoes::jsonb, '{notificacoes, sms}', 'true')
WHERE id = 1;

Aqui, o caminho {notificacoes, sms} é utilizado para acessar a chave sms dentro do objeto notificacoes e atualizar o valor para true.

Atualizando Múltiplas Chaves Simultaneamente

Suponha que, além de mudar o tema e sms, também precisamos atualizar o idioma para "en-US". Isso pode ser feito com múltiplos jsonb_set aninhados:

UPDATE usuarios
SET configuracoes = jsonb_set(
    jsonb_set(
        jsonb_set(configuracoes::jsonb, '{tema}', '"escuro"'),
        '{notificacoes, sms}', 'true'
    ),
    '{idioma}', '"en-US"'
)
WHERE id = 1;

Aqui estamos fazendo três atualizações ao mesmo tempo: modificando o tema, o sms em notificacoes, e o idioma.

Atualizando JSON com Base em Dados de Outra Tabela

Agora, vamos considerar um cenário um pouco mais complexo. Suponha que temos uma tabela produtos com um campo JSON chamado detalhes, que contém informações como o preço e a descrição do produto. Queremos atualizar esses valores dinamicamente com base nas informações de uma outra tabela atualizacoes_produto.

Estrutura da tabela produtos:

CREATE TABLE produtos (
    id SERIAL PRIMARY KEY,
    nome TEXT,
    detalhes JSONB
);

Dados exemplo:

{
  "preco": 100.00,
  "descricao": "Produto A",
  "disponibilidade": true
}

A tabela atualizacoes_produto pode conter novos preços e descrições:

CREATE TABLE atualizacoes_produto (
    produto_id INT,
    novo_preco NUMERIC,
    nova_descricao TEXT
);

Agora, queremos atualizar os produtos com as informações da tabela atualizacoes_produto. Podemos fazer isso da seguinte maneira:

WITH atualizacoes AS (
    SELECT p.id, ap.novo_preco, ap.nova_descricao
    FROM produtos p
    JOIN atualizacoes_produto ap ON p.id = ap.produto_id
)
UPDATE produtos p
SET detalhes = jsonb_set(
    jsonb_set(
        p.detalhes, '{preco}', to_jsonb(a.novo_preco)
    ),
    '{descricao}', to_jsonb(a.nova_descricao)
)
FROM atualizacoes a
WHERE p.id = a.id;

Nesse exemplo, estamos atualizando o campo JSON detalhes dos produtos com os novos preços e descrições vindos da tabela atualizacoes_produto. O to_jsonb converte os novos valores para o formato JSONB antes de inseri-los no campo detalhes.

Atualizando Objetos Dentro de Arrays no JSON

Se o campo JSON contiver um array de objetos, como em um cenário de respostas de um questionário, podemos usar a função jsonb_array_elements para iterar sobre os elementos e encontrar o objeto certo a ser atualizado.

Imagine que temos uma tabela questionario_respostas com um campo respostas que contém um array de respostas:

[
  {
    "id": "resposta1",
    "resposta": "Sim",
    "pontos": 10
  },
  {
    "id": "resposta2",
    "resposta": "Não",
    "pontos": 5
  }
]

Queremos atualizar a resposta e os pontos da resposta com o id "resposta1". Podemos fazer isso assim:

WITH resposta_correta AS (
  SELECT id, jsonb_array_elements(respostas) AS resposta
  FROM questionario_respostas
  WHERE id = 1
)
UPDATE questionario_respostas qr
SET respostas = jsonb_set(
    qr.respostas::jsonb,
    '{0, resposta}', '"Talvez"',
    true  -- Atualizando todos os níveis do JSON
)
FROM resposta_correta rc
WHERE qr.id = rc.id
AND rc.resposta->>'id' = 'resposta1';

Aqui, estamos iterando sobre o array e encontrando o objeto correto para atualizar sua resposta e pontos.

A função jsonb_set do PostgreSQL é extremamente poderosa e flexível para atualizar valores dentro de campos JSON. Com ela, é possível acessar e modificar chaves específicas de maneira eficiente, mesmo em estruturas complexas como arrays de objetos. Este artigo mostrou como lidar com diversas situações, desde atualizações simples até cenários mais avançados, como modificações baseadas em dados de outras tabelas e atualizações em arrays de objetos JSON.

Se você está lidando com dados semi-estruturados no PostgreSQL, conhecer a função jsonb_set é essencial para manter seus dados atualizados e acessíveis de forma eficiente.

Mais Posts

Design Pattern Facade em PHP : Exemplo prático

Design Pattern Facade em PHP : Exemplo prático

O Design Pattern Facade é uma solução elegante para simplificar a interface de um subsistema complexo, tornando-o mais fácil de... Leia mais

Como Instalar e Usar o MailHog com Laravel para Testes de Email

Como Instalar e Usar o MailHog com Laravel para Testes de Email

No desenvolvimento de aplicações web, especialmente no Laravel, enviar emails é uma tarefa comum. Porém, testar o envio de emails... Leia mais

A função WITH RECURSIVE no PostgreSQL

A função WITH RECURSIVE no PostgreSQL

A função WITH RECURSIVE no PostgreSQL é uma ferramenta poderosa para a execução de consultas recursivas em bancos de dados.... Leia mais

Como Instalar e Acessar o PostgreSQL no WSL com DBeaver

Como Instalar e Acessar o PostgreSQL no WSL com DBeaver

PostgreSQL é um dos sistemas de gerenciamento de banco de dados mais populares, conhecido por sua robustez e recursos avançados.... Leia mais