Usando o comando notify no Postgresql – vol. 1
O que faz o comando notify
O comando notify permite o envio de notificações para canais específicos no banco de dados. Trata-se de uma forma simples de permitir a comunicação de vários processos que usem o mesmo banco de dados. Aliados às triggers o desenvolvedor pode garantir que um processo qualquer fique sabendo que determinada operação foi bem sucedida.
Começando com algo simples
Para esse primeiro passo você pode usar um banco de dados já existente. Depois que acessar o shell do seu banco, execute os seguintes comandos:
postgres=# LISTEN teste; LISTEN
Vamos entender o que aconteceu.
O comando LISTEN acima registra a sessão atual como “ouvinte” das notificações do canal “teste”. Se na sessão atual já houver um canal “teste” previamente registrado nada acontece.
Depois que registramos um “ouvinte” é hora de enviar a notificação propriamente dita.
postgres=# NOTIFY teste; NOTIFY Asynchronous notification "teste" received from server process with PID 1234.
Pronto! Você acaba de receber sua primeira notificação diretamente do banco de dados! Repare que o servidor registra o recebimento da notificação ao retornar:
Asynchronous notification "teste" received from server process with PID 1234.
Essa funcionalidade é extremamente útil. Por exemplo: Você deseja receber uma notificação por email quando determinada tabela sofrer um update ou receber um novo registro. Basta criar uma trigger que seja executada sob esses eventos. Na trigger por sua vez você notifica o evento desejado.
Continuando com algo não tão simples
Vamos aumentar a complexidade dos nossos experimentos:
- Vamos criar um banco com apenas uma tabela;
- Em seguida vamos criar uma trigger a ser executada depois do insert;
- Registraremos o ouvinte de notificações;
- Na trigger por sua vez enviaremos as notificações;
Os códigos abaixo exigem um pouco mais de conhecimento sobre o Postgres; contudo, se trata de algo simples e fácil de acompanhar.
1 – Criando o banco:
createdb -U postgres -h localhost -W playground psql playground
Você pode usar outro nome para seu banco; aqui, por ser um banco para testes, usamos o nome playground – um lugar para “brincar”.
2 – Criando a tabela table_a:
playground=# create table table_a (nome varchar(512), email varchar(512));
2.1 – Criando uma função para notificar os eventos:
playground=# create function notify_trigger() returns trigger as $$ playground$# declare playground$# begin playground$# execute 'NOTIFY ' || TG_TABLE_NAME || '_' || TG_OP; playground$# return new; playground$# end; playground$# $$ language plpgsql; CREATE FUNCTION
Mais uma vez vamos entender o código.
1 – Na primeira linha, encontramos o trecho:
playground=# create function notify_trigger() returns trigger as $$Esse trecho cria a função notify_trigger().
As linhas seguintes são para declarar as variáveis, se necessári e indicar onde o “corpo” da função realmente começa.
2 – Ao ser executada, a função vai rodar o comando NOTIFY;
execute 'NOTIFY ' || TG_TABLE_NAME || '_' || TG_OP;3 – Repare nas variáveis TG_TABLE_NAME e TG_OP – essas são variáveis criadas automaticamente quando o Postgres roda a função criada. A TG_TABLE_NAME contém o nome da tabela que sofreu a operação e a variável TG_OP guarda o nome da operação que disparou a função;
3 – Criando as triggers:
playground=# create trigger table_a_trigger before insert or update on table_a execute procedure nofity_trigger();
4 – Vamos registrar o ouvinte (lembra do item 2.1.3 acima?):
playground=# LISTEN table_a_insert;
Finalmente, vamos efetuar um teste: vamos inserir um dado na tabela.
playground=# insert into table_a (nome, email) values ('algumacoisalegal', 'algumacoisalegal@meuservidordememail.com');
Veja o retorno do servidor:
INSERT 0 1 Asynchronous notification "table_a_insert" received from server process with PID 12345. # O numero PID no seu sistema vai ser diferente
Temos uma notificação para cada insert que fizermos na tabela table_a.
Agora é a sua vez de fazer um teste para os updates que fizermos na table_a. Lembre-se primeiro de registrar o ouvinte para os updates.
Essa foi apenas uma breve introdução nas notificações do Postgres.
No volume 2 vamos implementar um script python para receber as notificações do banco.
Referências
- Sobre triggers no postgres: https://www.postgresql.org/docs/9.2/static/plpgsql-trigger.html
- Para quem quer começar em postgres: https://www.postgresql.org/docs/9.6/static/tutorial-start.html
- Detalhes sobre o notify: https://www.postgresql.org/docs/8.3/static/sql-notify.html
- Códigos e detalhes interessantes sobre notify: http://www.divillo.com/