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

Come ripristinare dati specifici dal backup precedente su Postgres Heroku? (Es. Righe cancellate accidentalmente)

Riepilogo / TL;DR

In 3 passaggi potrai eseguire in modo molto semplice:

INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name -- backup_db being remote

Innanzitutto installa il backup in locale, in secondo luogo ottieni uno script SQL, in terzo luogo apri il tuo localhost al mondo esterno con ngrok .

Andiamo?

1. Scarica il file dump su Heroku e scaricalo da qualche parte:

  • Puoi farlo su un database remoto se hai dei server disponibili. Ma se come me non vuoi eseguire il provisioning di un altro database di produzione su Heroku o da qualche altra parte, lo farà assolutamente in locale.
  • Mi piace usare PGAdmin (disponibile su Linux, Mac e Windows), ma utilizzando la riga di comando e psql lo farà anche (leggendo questo posta per esempio)
  • In PGAdmin, dovresti Create a database . Quindi fai clic destro su di esso e usa il restore funzione. Seleziona il file dump, fai clic su Restore e sei pronto:i tuoi dati di backup sono disponibili localmente! Buon lavoro!

2. Accedi dal tuo database remoto

Volevo fare quanto segue:

SELECT * FROM backup_db.table_name
-- So I could then do
INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name

E sarei pronto. Super facile, vero? Abbastanza ovvio? Questo deve essere già stato fatto centinaia di volte. Ebbene no!

C'è un'utilità chiamata db_link in Postgres 9.1+, ma è piuttosto vincolante poiché si applica la seguente sintassi:

SELECT fname, lname FROM db_link('host=localhost dbname=backup-28-08', 'SELECT fname, lname FROM users') AS remote (varchar255 fname varchar255 lname)

Ogni nome di colonna deve essere ripetuto due volte incluso il suo tipo. Abbastanza pesante, siamo lontani dal semplice SELECT * FROM backup_db.table_name

Quindi l'idea qui è di usare lo information_schema contenuto della tabella, che descrive ogni tabella con i nomi delle colonne, i tipi, ecc. Ho trovato questa domanda su SO:Specifica l'elenco di definizioni delle colonne dblink da un tipo locale esistente che mi ha aiutato molto (Grazie bentrm ).

Ma la sua soluzione era un processo in due fasi, prima generando una funzione, quindi interrogandola:

SELECT dblink_star_func('dbname=ben', 'public', 'test');
SELECT * FROM star_test() WHERE data = 'success';

E stavo ancora puntando a un 1 liner. Dopo un po' di dolore (non essere un guru di SQL), ecco il Gist:https://gist.github. com/augnustin/d30973ea8b5bf0067841

Ora posso fare:

SELECT * FROM remote_db(NULL::users) -- (Still not 100% about why I need the NULL::)
-- And also
INSERT INTO users
SELECT * FROM remote_db(NULL::users)

Fantastico, vero?

3. Accedi a localhost da remoto

Se il tuo database remoto è già disponibile da Internet (=ha un indirizzo IP, un nome di dominio Es. per Heroku sarà simile a:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p ) puoi saltare questo passaggio . Ma se usi il tuo database locale, devi renderlo disponibile dal mondo esterno (in modo che il database di Heroku possa accedervi).

Per questo, utilizzo il meraviglioso ngrok .

Una volta installato devo solo inserire il seguente comando:

ngrok -proto=tcp 5432 #5432 being the default port for Postgresql. (Adapt if necessary)
                                                                                                                                                                                                    
Tunnel Status                 online                                                                                                                                                                
Version                       1.7/1.6                                                                                                                                                               
Forwarding                    tcp://ngrok.com:51727 -> 127.0.0.1:5432                                                                                                                               
Web Interface                 127.0.0.1:4040                                                                                                                                                        
# Conn                        0                                                                                                                                                                     
Avg Conn Time                 0.00ms    

E devi solo collegare db_link (nel succo) su host=ngrock.com port=51727 e sei a posto !

4. Andare oltre

Ci sono molti possibili miglioramenti a questo. Eccone alcuni che già vedo:

  • Considerando lo script come una funzionalità predefinita per db_link funzione
  • Essere più a prova di errore se le strutture del database sono diverse nel backup e nella produzione
  • Strumento di confronto tra i risultati del database e i risultati del backup (per restituire solo linee di differenza)
  • Gestire join semplici
  • E ancora di più sarebbe avere un adattatore a livello di applicazione (es. ActiveRecord in Rails) che potrebbe consentire la manipolazione di oggetti back-end invece di SQL grezzo come ora

Spero di essere stato chiaro! Si prega di chiedere maggiori dettagli in caso contrario