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:
-
Useformat()
para escapar das cordas de forma mais elegante.
-
Passe a linha inteira em vez de passar e escapar de cada coluna.
-
Não coloque a senha em cada função de gatilho.
Use umFOREIGN SERVER
maisUSER MAPPING
. Instruções detalhadas aqui:
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: