PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Trigger para inserir linhas no banco de dados remoto após a exclusão


Esta é uma aplicação limitada de replicação. Os requisitos variam muito, por isso existem várias soluções estabelecidas diferentes, abordando diferentes situações. Considere a visão geral do manual.

Sua solução feita à mão e baseada em gatilhos é uma opção viável para relativamente poucos exclusões. Abrir e fechar uma conexão separada para cada linha gera bastante sobrecarga. Existem outras várias opções.

Enquanto trabalhando com dblink sugiro algumas modificações. Mais importante:

Basicamente, execute uma vez no servidor de origem:
CREATE SERVER myserver FOREIGN DATA WRAPPER dblink_fdw
OPTIONS (hostaddr '127.0.0.1', dbname 'gtr_bd_archive');

CREATE USER MAPPING FOR role_source SERVER myserver
OPTIONS (user 'postgres', password 'secret');

De preferência, não faça login como superusuário no servidor de destino. Use uma função dedicada com privilégios limitados para evitar o escalonamento de privilégios.

E use um arquivo de senha no servidor de destino para permitir acesso sem senha. Dessa forma, você nem precisa armazenar a senha no USER MAPPING . Instruções no último capítulo desta resposta relacionada:

Então:
CREATE OR REPLACE FUNCTION pg_temp.flux_tresorerie_historique_backup_row()
  RETURNS trigger AS
$func$
BEGIN
   PERFORM dblink_connect('myserver');  -- name of foreign server from above

   PERFORM dblink_exec( format(
   $$
   INSERT INTO flux_tresorerie_historique  -- provide target column list!
   SELECT (r).id_flux_historique
        , (r).date_operation_flux
        , (r).date_valeur_flux
        , (r).date_rapprochement_flux::date  -- 'YYYY-MM-DD' is default ISO format anyway
        , (r).libelle_flux
        , (r).montant_flux
        , (r).contre_valeur_dzd
        , (r).rib_compte_bancaire
        , (r).frais_flux
        , (r).sens_flux
        , (r).statut_flux
        , (r).code_devise
        , (r).code_mode_paiement
        , (r).code_agence
        , (r).code_compte
        , (r).code_banque
        , (r).date_maj_flux
        , (r).statut_frais
        , (r).reference_flux
        , (r).code_commission
        , (r).id_flux
   FROM   (SELECT %L::flux_tresorerie_historique) t(r)
   $$, OLD::text));  -- cast whole row type

   PERFORM dblink_disconnect();
   RETURN NULL;  -- only for AFTER trigger
END
$func$  LANGUAGE plpgsql;

Você deve soletrar a lista de colunas para a tabela de destino se os tipos de linha não corresponderem.

Se você é sério sobre isso:

Ou seja, você insere a linha inteira e o tipo de linha de destino é idêntico (sem extrair uma data de um carimbo de data/hora etc.), você pode simplificar muito mais a passagem de toda a linha.
CREATE OR REPLACE FUNCTION flux_tresorerie_historique_backup_row()
  RETURNS trigger AS
$func$
BEGIN
   PERFORM dblink_connect('myserver');  -- name of foreign server

   PERFORM dblink_exec( format(
   $$
   INSERT INTO flux_tresorerie_historique
   SELECT (%L::flux_tresorerie_historique).*
   $$
   , OLD::text));

   PERFORM dblink_disconnect();
   RETURN NULL;  -- only for AFTER trigger
END
$func$  LANGUAGE plpgsql;

Relacionado: