Esta es una aplicación limitada de replicación. Los requisitos varían mucho, por lo que hay una serie de diferentes soluciones establecidas, que abordan diferentes situaciones. Considere la descripción general del manual.
Su solución tejida a mano basada en disparadores es una opción viable para relativamente pocos eliminaciones Abrir y cerrar una conexión separada para cada fila genera una gran sobrecarga. Hay otras varias opciones.
Mientras trabajando con dblink sugiero algunas modificaciones. Lo más importante:
-
Usar
format()
para escapar de las cuerdas con más elegancia. -
Pase la fila completa en lugar de pasar y escapar de cada columna.
-
No coloque la contraseña en cada una de las funciones de activación.
Utilice unFOREIGN SERVER
másUSER MAPPING
. Instrucciones detalladas aquí:
Básicamente, ejecuta una vez en el servidor de origen:
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');
Preferiblemente, no inicie sesión como superusuario en el servidor de destino. Use un rol dedicado con privilegios limitados para evitar la escalada de privilegios.
Y use un archivo de contraseña
en el servidor de destino para permitir el acceso sin contraseña. De esta manera, ni siquiera tiene que almacenar la contraseña en el USER MAPPING
. Instrucciones en el último capítulo de esta respuesta relacionada:
Entonces:
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;
Debe deletrear la lista de columnas para la tabla de destino si los tipos de fila no coinciden.
Si hablas en serio sobre esto:
Es decir, inserta la fila completa y el tipo de fila de destino es idéntico (sin extraer una fecha de una marca de tiempo, etc.), puede simplificar mucho más pasar la fila completa.
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: