Il s'agit d'une application limitée de la réplication. Les exigences varient beaucoup, il existe donc un certain nombre de solutions établies différentes, répondant à différentes situations. Considérez l'aperçu du manuel.
Votre solution artisanale basée sur des déclencheurs est une option viable pour relativement peu suppressions. L'ouverture et la fermeture d'une connexion distincte pour chaque ligne entraîne une surcharge importante. Il existe d'autres options.
Pendant que travailler avec dblink je suggère quelques modifications. Le plus important :
-
Utilisez
format()
pour échapper les chaînes plus élégamment. -
Passez la ligne entière au lieu de passer et d'échapper à chaque colonne.
-
Ne placez pas le mot de passe dans chaque fonction de déclenchement.
Utilisez unFOREIGN SERVER
plusUSER MAPPING
. Instructions détaillées ici :
Fondamentalement, exécutez une fois sur le serveur source :
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 préférence, ne vous connectez pas en tant que superutilisateur sur le serveur cible. Utilisez un rôle dédié avec des privilèges limités pour éviter l'escalade des privilèges.
Et utilisez un fichier de mot de passe
sur le serveur cible pour permettre un accès sans mot de passe. De cette façon, vous n'avez même pas besoin de stocker le mot de passe dans le USER MAPPING
. Instructions dans le dernier chapitre de cette réponse connexe :
Ensuite :
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;
Vous devez épeler la liste des colonnes de la table cible si les types de lignes ne correspondent pas.
Si vous êtes sérieux à ce sujet :
C'est-à-dire que vous insérez la ligne entière et que le type de ligne cible est identique (pas d'extraction de date à partir d'un horodatage, etc.), vous pouvez simplifier beaucoup plus en passant toute la ligne.
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;
Connexe :