sql >> Database >  >> RDS >> PostgreSQL

Hoe kan ik specifieke gegevens van een eerdere back-up op Postgres Heroku herstellen? (Bijvoorbeeld per ongeluk verwijderde rijen)

Samenvatting / TL;DR

In 3 stappen kunt u heel eenvoudig uitvoeren:

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

Installeer eerst de back-up lokaal, verkrijg ten tweede een SQL-script, ten derde open je localhost naar de buitenwereld met ngrok .

Laten we gaan?

1. Download uw dumpbestand op Heroku en dump het ergens:

  • Je kunt dat doen op een externe database als je servers beschikbaar hebt. Maar als je, net als ik, geen andere productiedatabase op Heroku of ergens anders wilt voorzien, is lokaal voldoende.
  • Ik gebruik graag PGAdmin (beschikbaar op Linux, Mac en Windows), maar met gebruik van de opdrachtregel en psql zal ook doen (door deze posten door voorbeeld)
  • In PGAdmin doet u Create a database . Klik er dan met de rechtermuisknop op en gebruik de restore functie. Selecteer uw dumpbestand, klik op Restore en je bent helemaal klaar:je back-upgegevens zijn lokaal beschikbaar! Goed gedaan!

2. Open het vanuit uw externe database

Ik wilde het volgende doen:

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

En ik zou helemaal klaar zijn. Super makkelijk, toch? Vrij duidelijk? Dit moet al honderden keren zijn gedaan. Nou, nee!

Er is een hulpprogramma genaamd db_link in Postgres 9.1+, maar het is behoorlijk beperkend omdat de volgende syntaxis van toepassing is:

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

Elke kolomnaam moet twee keer worden herhaald, inclusief het type. Vrij zwaar, we zijn verre van de eenvoudige SELECT * FROM backup_db.table_name

Dus het idee hier is om het information_schema . te gebruiken tabelinhoud, die elke tabel beschrijft met de kolomnamen, de typen enz. Ik vond deze vraag op SO:Specificeer dblink kolomdefinitielijst van een lokaal bestaand type wat me veel heeft geholpen (Bedankt bentrm ).

Maar de oplossing was een proces van twee stappen, eerst een functie genereren en deze vervolgens opvragen:

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

En ik mikte nog steeds op een 1-liner. Na wat pijn (geen SQL-goeroe zijn), is hier de samenvatting:https://gist.github. com/augnustin/d30973ea8b5bf0067841

Ik kan nu het volgende doen:

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)

Geweldig, toch?

3. Toegang krijgen tot localhost op afstand

Als uw externe database al beschikbaar is vanaf internet (=heeft een IP-adres, een domeinnaam, bijvoorbeeld voor Heroku, ziet het er als volgt uit:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p ) je kunt deze stap overslaan . Maar als u uw lokale database gebruikt, moet u deze van de buitenwereld beschikbaar maken (zodat de Heroku-database er toegang toe heeft).

Hiervoor gebruik ik de prachtige ngrok .

Eenmaal geïnstalleerd hoef ik alleen de volgende opdracht in te voeren:

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    

En u hoeft alleen db_link . aan te sluiten (in wezen) naar host=ngrock.com port=51727 en je bent goed om te gaan !

4. Verder gaan

Hierin zijn veel verbeteringen mogelijk. Hier zijn er een paar die ik al zie:

  • Het script beschouwen als een standaardfunctie voor db_link functie
  • Foutbestendiger zijn als databasestructuren verschillen in back-up en productie
  • Een vergelijkingstool maken tussen databaseresultaten en back-upresultaten (om alleen afwijkende regels terug te geven)
  • Eenvoudige joins afhandelen
  • En nog verder zou het hebben van een adapter op applicatieniveau (bijv. ActiveRecord in Rails) die manipulatie van backend-objecten mogelijk zou maken in plaats van onbewerkte SQL zoals nu

Hoop dat ik duidelijk was! Vraag anders om meer details




  1. Nieuwe AMD-processorfamilies zijn goed te vergelijken met nieuwe Intel-processors

  2. Bijwerken en verwijderen van gerelateerde modellen (relatietabellen) in Yii

  3. Hoe maak je een groei-babygrafiek met gegevens in mysql +PDO

  4. Batchbestand om mysql te verbinden en opdrachten uit te voeren