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

Hvordan gendanner man specifikke data fra tidligere backup på Postgres Heroku? (F.eks. Slettede rækker ved et uheld)

Oversigt / TL;DR

I 3 trin vil du være i stand til at udføre meget enkelt:

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

Først skal du installere sikkerhedskopien lokalt, for det andet få et SQL-script, for det tredje åbne din lokale vært til omverdenen med ngrok .

Lad os gå?

1. Download din dump-fil på Heroku og dump det et sted:

  • Du kan gøre det på en ekstern database, hvis du har nogle servere til rådighed. Men hvis du ligesom mig ikke ønsker at klargøre en anden produktionsdatabase på Heroku eller et andet sted, vil lokalt helt gøre det.
  • Jeg kan godt lide at bruge PGAdmin (tilgængelig på Linux, Mac og Windows), men ved hjælp af kommandolinje og psql vil også gøre det (ved at læse denne indlæg ved eksempel)
  • I PGAdmin skal du Create a database . Højreklik derefter på den og brug restore fungere. Vælg din dumpfil, klik på Restore og du er klar:dine backupdata er tilgængelige lokalt! Godt arbejde!

2. Få adgang til den fra din fjerndatabase

Jeg ønskede at gøre følgende:

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

Og jeg ville være klar. Super nemt, ikke? Ret indlysende? Dette må allerede være blevet gjort hundredvis af gange. Nå, nej!

Der er et hjælpeprogram kaldet db_link i Postgres 9.1+, men det er ret begrænsende, da følgende syntaks gælder:

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

Hvert kolonnenavn skal gentages to gange inklusive dens type. Temmelig tungt, vi er langt fra den simple SELECT * FROM backup_db.table_name

Så ideen her er at bruge information_schema tabelindhold, som beskriver hver tabel med dens kolonnenavne, dens typer osv. Jeg fandt dette spørgsmål på SO:Angiv dblink-kolonnedefinitionsliste fra en lokal eksisterende type hvilket hjalp mig meget (Tak bentrm ).

Men dens løsning var en proces i to trin, først generering af en funktion og derefter forespørgsel på den:

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

Og jeg sigtede stadig efter en 1 liner. Efter lidt smerte (ikke at være en SQL-guru), her er hovedindholdet:https://gist.github. com/augnustin/d30973ea8b5bf0067841

Jeg kan nu:

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)

Fantastisk, ikke?

3. Få fjernadgang til localhost

Hvis din fjerndatabase allerede er tilgængelig fra internettet (=har en IP-adresse, et domænenavn F.eks. for Heroku vil det se ud som:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p ) du kan springe dette trin over . Men hvis du bruger din lokale database, skal du gøre den tilgængelig fra omverdenen (så Heroku-databasen kan få adgang til den).

Til dette bruger jeg den vidunderlige ngrok .

Når den er installeret, behøver jeg kun at indtaste følgende kommando:

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    

Og du behøver kun at tilslutte db_link (i det væsentlige) til host=ngrock.com port=51727 og du er god til at gå !

4. Gå videre

Der er mange mulige forbedringer til dette. Her er nogle, jeg allerede ser:

  • Betragtning af scriptet som en standardfunktion til db_link funktion
  • Vær mere fejlsikker, hvis databasestrukturer er forskellige i backup og produktion
  • Sådan laves sammenligningsværktøj mellem databaseresultater og backupresultater (for kun at returnere forskellige linjer)
  • Håndter simple joins
  • Og endnu mere ville være at have en applikationsniveauadapter (f.eks. ActiveRecord in Rails), der kunne tillade manipulation af backend-objekter i stedet for rå SQL som nu

Håber jeg var klar! Spørg venligst om flere detaljer ellers




  1. Ruby sort_by for arrays returneret af MySQL, dato formateret som streng

  2. 4 måder at få information om en tabels struktur i SQLite

  3. Hvad er der galt med denne SQL Server-forespørgselsdelingsberegning?

  4. XAMPP/MySQL:kunne ikke åbne single-table tablespace-filen .\mysql\innodb_index_stats.ibd efter genstart af MySQL