DB Dump mit psycopg2

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Hallo,
suche nach einer Möglichkeit mit psycopg2 ein Backup einer Postgre Datenbank zu machen (hätte gern ein SQL File).
Bei sqlite3 gibt es dafür die Funktion "iterdump".
Gibt es für psycopg2 eine ähnliche Funktion?

Gibt es irgendwo eine Referenz für psycopg2? Auf der offiziellen Seite gibt es ja gar nichts und mit Google wurde leider auch nichts passendes gefunden.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

ice2k3 hat geschrieben:suche nach einer Möglichkeit mit psycopg2 ein Backup einer Postgre Datenbank zu machen
Hallo ice2k3!

psycopg2 hat nichts damit zu tun. Das ist nur die Schnittstelle zur Datenbank. Für einen Dump ist das Kommandozeilenprogramm ``pg_dump`` zuständig. Informationen darüber, findest du in der mitgelieferten PostgreSQL-Hilfe.

mfg
Gerold
:-)

PS: Informationen über die Sicherung findest du im Kapitel "Server Administration" > "Backup and Restore".

EDIT: ``gp_dump`` --> ``pg_dump`` (danke Pekh) :-)

.
Zuletzt geändert von gerold am Freitag 23. Januar 2009, 10:34, insgesamt 2-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

'pg_dump' :wink:
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Ich möchte das Backup ja vom Python Client aus starten und auf dem Client dann auch abspeichern.
Mit sqlite3 mach ich das so:

Code: Alles auswählen

def dump(self):
        f = open('dump.sql', 'w')
        for line in self.connection.iterdump():
            f.write('%s\n' % line)
        f.close()
Jetzt suche ich eine äquivalente Funktion von psycopg2.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

ice2k3 hat geschrieben:Ich möchte das Backup ja vom Python Client aus starten und auf dem Client dann auch abspeichern.
Hallo ice2k3!

SQLite ist eine Desktop-Datenbank, die nur aus einer Datei besteht. Es läuft kein eigenständiges Programm im Hintergund, welches die Datenbank verwaltet. Die Datei wird direkt von pysqlite geöffnet und bearbeitet. Das heißt, dass pysqlite den kompletten Code für die Verwaltung der Datenbank enthält. Eine Datensicherung einer SQLite-Datenbank ist normalerweise das Kopieren der Datei. Dass es auch vom Programm aus funktioniert, aus dem gesamten Dateninhalt ein SQL-Skript zu generieren, ist nicht Standard und ein Zusatzfeature von pysqlite.

MySQL oder PostgreSQL sind keine Desktopdatenbanken. Dahinter steht jeweils ein eigenständiger Prozess, welcher die Daten verwaltet. Solche Datenbanken werden normalerweise über das Netzwerk angesprochen. Und ein Backup macht der, der direkten Zugriff auf den Computer hat. Man kann die Ausgabe des Dump-Programmes natürlich auch umleiten und an einen Client schicken. Das macht z.B. phpMyAdmin so. Da wird der Dump vom Webserver an den Client geschickt. Ich muss jetzt zugeben, dass mir im Moment kein Befehl einfällt, mit dem der Dump direkt vom Server zum Client übertragen werden kann.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Die Aussage, dass das mit psycopg2 nicht zu realisieren ist, hätte mir gereicht. Der Rest ist bekannt ;)

Muss mir mal überlegen, ob und wie ich das dann realisieren könnte.

Edit: Lässt sich der pg_dump Befehl auch ohne Eingabe des Passworts ausführen (Parameter o.ä.) ?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

ice2k3 hat geschrieben:Die Aussage, dass das mit psycopg2 nicht zu realisieren ist, hätte mir gereicht. Der Rest ist bekannt ;)
Hallo ice2k3!

Das ist Teil meines Denkprozesses. Du stellst eine Frage -- ich mache mir Gedanken darüber, ob und wie das machbar ist. Und wärend ich darüber nachdenke, schreibe ich.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Gut, ich habe weiter nachgedacht.

PostgreSQL kann Python!

Also brauche ich nur eine Python-Funktion erstellen, welche einen Dump macht und diesen Zeile für Zeile zurück gibt.

Also zuerst mal eine Testdatenbank erstellen. Dann eine Testtabelle. Und dann noch mit ``CREATE LANGUAGE plpythonu`` Python aktivieren.

Dann kommt die Funktion:

Code: Alles auswählen

CREATE OR REPLACE FUNCTION "public"."pythonbackup" () RETURNS SETOF text AS
$body$
import os
import subprocess

os.environ["PGPASSWORD"] = "EinPasswort"
args = [
    r"J:\Programme\PostgreSQL\8.3\bin\pg_dump.exe", "--inserts", 
    "--username=postgres", "testdb"
]
proc = subprocess.Popen(
    args, stdout = subprocess.PIPE, env = os.environ
)
for line in proc.stdout:
    yield line.rstrip()
$body$
LANGUAGE 'plpythonu'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100 ROWS 1000;
Die Funktion habe ich mit dem "SQL Manager 2007 Lite" erstellt, deshalb sieht die so formatiert aus.

Dann noch ein kleiner Test -- nach vielen Fehlversuchen -- es funktioniert. :-)

Jetzt kann man mit ``SELECT * FROM pythonbackup()`` den Datenbank-Dump abfragen. Die Funktion ist nicht sonderlich fehlertolerant, aber sie zeigt, wie es funktionieren könnte.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Code: Alles auswählen

os.environ["PGPASSWORD"] = "EinPasswort" 
args = [ 
    r"J:\Programme\PostgreSQL\8.3\bin\pg_dump.exe", "--inserts", 
    "--username=postgres", "testdb" 
] 
proc = subprocess.Popen( 
    args, stdout = subprocess.PIPE, env = os.environ 
) 
for line in proc.stdout: 
    yield line.rstrip() 
Ich versuche diesen Code mal auf dem Client auszuführen. (Hol mir einfach den "bin" Ordner vom Server). Host kann man ja auch noch als Parameter übergeben. Werd ich allerdings dann erst am Montag machen.

Bin mir nur nicht sicher ob das environ ohne Admin-Rechte überhaupt geht?! Naja, werd mal testen und mich nochmal melden.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

ice2k3 hat geschrieben:Bin mir nur nicht sicher ob das environ ohne Admin-Rechte überhaupt geht?!
Wieso sollte es nicht? Ist ja schließlich nicht so, als ob man damit irgendwelchen Unfug treiben könnte.

Allerdings ist es IMHO ziemlich sinnlos, da wenn ``env`` nicht definiert wird, automatisch das Environment des Eltern-Prozesses (das über ``os.environ`` zugreifbar ist) hergenommen wird.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Leonidas hat geschrieben:Allerdings ist es IMHO ziemlich sinnlos, da wenn ``env`` nicht definiert wird, automatisch das Environment des Eltern-Prozesses (das über ``os.environ`` zugreifbar ist) hergenommen wird.
Hallo Leonidas!

Stimmt natürlich. Das ist ein Rest meiner vielen Versuche, den ich übersehen habe.

Hier die korrigierte Version:

Code: Alles auswählen

import os
import subprocess

os.environ["PGPASSWORD"] = "ein_passwort"
args = [
    r"J:\Programme\PostgreSQL\8.3\bin\pg_dump.exe", "--inserts", 
    "--username=postgres", "testdb"
]
proc = subprocess.Popen(args, stdout = subprocess.PIPE)
for line in proc.stdout:
    yield line.rstrip()
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten