Questa è un'applicazione limitata di replica. I requisiti variano molto, quindi esistono diverse soluzioni consolidate, che affrontano situazioni diverse. Considera la panoramica nel manuale.
La tua soluzione manuale e basata su trigger è un'opzione praticabile per relativamente pochi eliminazioni. L'apertura e la chiusura di una connessione separata per ogni riga comporta un notevole sovraccarico. Ci sono altre varie opzioni.
Mentre lavorando con dblink suggerisco alcune modifiche. Soprattutto:
-
Usa
format()
per sfuggire alle corde in modo più elegante. -
Supera l'intera riga invece di passare ed eseguire l'escape di ogni singola colonna.
-
Non inserire la password in ogni singola funzione trigger.
Utilizza unFOREIGN SERVER
piùUSER MAPPING
. Istruzioni dettagliate qui:
Fondamentalmente, esegui una volta sul server di origine:
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');
Preferibilmente, non accedere come superutente al server di destinazione. Utilizza un ruolo dedicato con privilegi limitati per evitare l'escalation dei privilegi.
E usa un file di password
sul server di destinazione per consentire l'accesso senza password. In questo modo non devi nemmeno memorizzare la password nella USER MAPPING
. Istruzioni nell'ultimo capitolo di questa risposta correlata:
Quindi:
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;
Dovresti precisare l'elenco delle colonne per la tabella di destinazione se i tipi di riga non corrispondono.
Se sei serio su questo:
Cioè, inserisci l'intera riga e il tipo di riga di destinazione è identico (nessuna estrazione di una data da un timestamp ecc.), puoi semplificare ulteriormente il passaggio dell'intera riga.
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;
Correlati: