PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Attiva per inserire righe nel database remoto dopo l'eliminazione

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 un FOREIGN 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: