sqlite3 - Datenbank print in txt?

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
degon
User
Beiträge: 28
Registriert: Montag 14. Juni 2010, 12:03

Hi,

ich habe ein folgendes Problem. Ich habe mehrere Datenbanken, die ich in eine txt Datei geprintet haben möchte, und zwar genauso wie sie in der db sind. Wie ist sowas möglich? Jmd eine Idee?

Grüße, degon
BlackJack

@degon: Mit dem entsprechenden Werkzeug der Datenbanksoftware einfach einen Dump des Inhalts erstellen!?
degon
User
Beiträge: 28
Registriert: Montag 14. Juni 2010, 12:03

Ich habe schon einiges probiert, aber ich komme nicht drauf. Ich bin schon bei einzelnen Arrays für eine Spalte, aber soweit hat mich das auch nicht gebracht.

Beim dump muss ich immer an pickle denken, das meinst du aber nicht oder?
BlackJack

@degon: Ich meinte das ``.dump``-Kommando vom ``sqlite3``-Programm. Also nicht mit Python, sondern eben die übliche Art wie man eine Datenbank in einer Textdatei exportiert, ohne dass Informationen verloren gehen.
degon
User
Beiträge: 28
Registriert: Montag 14. Juni 2010, 12:03

Mhhh, dann bekomme ich praktisch immer ein Protokoll dessen was getan wurde...

BEGIN TRANSACTION;
CREATE TABLE Eins(Energy FLOAT, FPulse FLOAT, FPulseErr FLOAT, SPulse FLOAT, SPulseErr FLOAT);
INSERT INTO "Eins" VALUES(0.0,-1507.556,35.359,483.556,6.039);
INSERT INTO "Eins" VALUES(0.0,-1507.556,35.359,483.556,6.039);
INSERT INTO "Eins" VALUES(0.0,-1507.556,35.359,483.556,6.039);
INSERT INTO "Eins" VALUES(12.0,-1507.556,35.359,483.556,6.039);
INSERT INTO "Eins" VALUES(12.0,-1507.556,35.359,483.556,6.039);
INSERT INTO "Eins" VALUES(12.0,-1507.556,35.359,483.556,6.039);
COMMIT;


mit

Code: Alles auswählen

        data = '\n'.join(self.connection.iterdump())        
        with open('dump.sql', 'w') as dumpfile:
            dumpfile.write(data)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

degon hat geschrieben:Mhhh, dann bekomme ich praktisch immer ein Protokoll dessen was getan wurde...

BEGIN TRANSACTION;
CREATE TABLE Eins(Energy FLOAT, FPulse FLOAT, FPulseErr FLOAT, SPulse FLOAT, SPulseErr FLOAT);
INSERT INTO "Eins" VALUES(0.0,-1507.556,35.359,483.556,6.039);
[...]
INSERT INTO "Eins" VALUES(12.0,-1507.556,35.359,483.556,6.039);
COMMIT;
Wie kommst du auf das schmale Brett, dass das ein Log der Aktivitäten sein soll? UPDATEs und DELETEs wirst du dort nicht finden. Das sind einfach die SQL-Statements die dir die Datenbank wieder aufbauen.
degon
User
Beiträge: 28
Registriert: Montag 14. Juni 2010, 12:03

Ja gut, dann eben das. Sieht aber aus wie ein logfile. Bringt mich aber auch nicht weiter :(
BlackJack

@degon: Warum bringt Dich das nicht weiter? Was ist denn das Ziel der Aktion?
degon
User
Beiträge: 28
Registriert: Montag 14. Juni 2010, 12:03

Ich brauche einen exakten Abdruck einer DB in einem txt file. So bescheuert das klingt, das Programm fuer die weitere Auswertung muss mit solchen Daten gefuettert werden. d.h.

Col1 Col2 Col3 ....
var var....
var var
var var
var var....

ist sowas ueberhaupt drin? Kann man das ueber arrays umgehen und dann arrays in die files mit tab reinschreiben?
deets

Das ist nicht eine "exakter Abdruck einer DB" - wie kommst du darauf, dass ein DB so "innendrin" aussieht?

Das ist ein CSV-File, und das kannst du einfach mit dem Modul csv aus der Standardbibliothek erstellen. Dafuer findest du hier im Forum ausreichend Hinweise.
degon
User
Beiträge: 28
Registriert: Montag 14. Juni 2010, 12:03

ah herzlichen Dank, das hat genau gepasst!

Code: Alles auswählen

        self.SQLinsert = "SELECT * FROM" + " " + str(self.tablename)
        self.cursor.execute(self.SQLinsert)
        csv_writer = csv.writer(open("out.csv", "wt"), delimiter = ',')
        csv_writer.writerow([i[0] for i in self.cursor.description]) # write headers
        csv_writer.writerows(self.cursor)
        del csv_writer # this will close the CSV file
Also so wird eine Sqlite in eine CSV geschrieben mit Header.
mal ne andere Frage, kann man mein self.SQLinsert auch irgendwie etwas besser gestalten, das sieht so zusammengefrickelt aus :)
BlackJack

@degon: Der Name ist irreführend, weil es sich ja gar nicht um ein ``INSERT`` handelt. Nenn das doch einfach nur `sql`. Und dann ist es etwas sinnfrei das literale Leerzeichen mit ``+`` an eine literale Zeichenkette zu setzen. Ist der `str()`-Aufruf auf `self.tablename` notwendig?

Die letzte Zeile ist Unsinn. Das schliesst nicht die Datei sondern löscht den Namen `csv_writer` aus dem aktuellen Namensraum. Das kann dazu führen das über mehrere Ecken die Datei geschlossen wird, aber garantiert wird das von der Sprache nicht. Wenn Du die Datei schliessen willst, dann ruf die `close()`-Methode auf dem Dateiobjekt auf oder verwende die ``with``-Anweisung.

``del`` zum Löschen von Namen braucht man nur ganz selten. Wenn man so etwas macht, sollte man sich immer fragen ob das sein muss, oder ob sich das Problem nicht auch anders lösen lässt.
deets

Ich wuerde auch noch hinzufuegen, dass "self.SQLInsert" als Instanz-Variable unnoetig ist. Man sollte immer so sparsam wie moeglich mit Zustand sein, und da du dieses Statement eh immer lokal zusammenbaust, sollte es auch eine lokale Variable sein.
degon
User
Beiträge: 28
Registriert: Montag 14. Juni 2010, 12:03

@BlackJack: Ja der Aufruf ist definitiv notwendig. Gibt es bei soetwas elegantere Methoden? Der Tablename wird bei einem GUI aus einem Entry Fenster gezogen.

@deets: Alles klar, mache ich!
Antworten