Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
|
python:psycopg [2023/06/30 21:44] root |
python:psycopg [2023/07/01 00:00] (aktuell) root [Copy] |
||
|---|---|---|---|
| Zeile 60: | Zeile 60: | ||
| * oder auch | * oder auch | ||
| * ^ deswegen kann man im gleichen execute()-Aufruf keine Kommandos mischen die Transaktionen unterstützen und solche die es nicht tun | * ^ deswegen kann man im gleichen execute()-Aufruf keine Kommandos mischen die Transaktionen unterstützen und solche die es nicht tun | ||
| + | |||
| + | |||
| + | ===== Temporary tables ====== | ||
| + | |||
| + | * Existieren nur in der Session in der sie erstellt wurden | ||
| + | * verschiedene Verbindungen zur Datenbank können also die gleiche Tabelle ggf. mit unterschiedlichem Inhalt haben | ||
| + | |||
| + | <sxh sql> | ||
| + | create temp table somename (somerow varchar) on commit delete rows; | ||
| + | </ | ||
| + | |||
| + | * "on commit" | ||
| + | * preserve_rows (Default in postgres, aber nicht im Standard) -> erhalte die Tabelle wie sie ist, inkl. Inhalt | ||
| + | * delete rows -> truncate aka. lösche alle Einträge, aber erhalte die leere Tabelle | ||
| + | * drop -> lösche die Tabelle | ||
| + | |||
| + | |||
| + | ===== Copy ====== | ||
| + | |||
| + | * Eigentlich eine Möglichkeit eine größere Menge Einträge aus Dateien (oder stdin) einzulesen oder nach stout/Datei auszugeben | ||
| + | * ist meist effizienter als insert into | ||
| + | * statt einer Tabelle kann man auch sub-select-Statements benutzen | ||
| + | * schlägt das einfügen eines Datensatzes fehl wird alles rückabgewickelt | ||
| + | * im Gegensatz zu insert into gibt es kein "on conflict" | ||
| + | * es dürfen also auch keine Doubletten in den Daten sein (die einen unique-Spalte betreffen würden) | ||
| + | |||
| + | |||
| + | Daten in eine Tabelle einfügen: | ||
| + | <sxh python> | ||
| + | with cursor.copy(" | ||
| + | for record in records: | ||
| + | copy.write_row(record) | ||
| + | </ | ||
| + | * record muss dabei ein iterateable sein, auch wenn nur eine Spalte eingefügt wird | ||
| + | * also zum Beispiel ein tuple | ||
| + | * liegt daran das es auch mehrere Spalten sein könnten -> (spalte1, spalte2 usw.) | ||
| + | |||
| + | Daten aus einer Tabelle auslesen: | ||
| + | <sxh python> | ||
| + | with cursor.copy(" | ||
| + | for record in copy.rows(): | ||
| + | Some action | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | Traceback (most recent call last): | ||
| + | File " | ||
| + | copy.write_row(word) | ||
| + | File "/ | ||
| + | next(self.gen) | ||
| + | File " | ||
| + | raise ex.with_traceback(None) | ||
| + | psycopg.errors.BadCopyFileFormat: | ||
| + | CONTEXT: | ||
| + | </ | ||
| + | |||
| + | ^ Hier wurde vergessen das der Datensatz für die Spalte ein Iterateable sein muss. \\ | ||
| + | Daher wurde " | ||
| + | |||
| + | Fehlschlagender Code (Beispiel): | ||
| + | |||
| + | <sxh python> | ||
| + | names = [" | ||
| + | with cursor.copy(" | ||
| + | for name in names: | ||
| + | copy.write_row(name) | ||
| + | </ | ||
| + | |||
| + | * Daten werden aus einem iterateable names gelesen | ||
| + | * name ist eine Zeichenkette | ||
| + | * copy.write_row erwartet aber einen Datensatz | ||
| + | * ein Datensatz ist ein iterateable -> ein tuple, eine Liste usw. | ||
| + | * hier wurde ein String übergeben -> ein String ist auch ein iterateable -> also wird über den String iteriert | ||
| + | * da der String länger ist als die Menge der Spalten -> es gibt nur eine, kommt es zum Fehler | ||
| + | |||
| + | Hier sollte man auch aufpassen: | ||
| + | <sxh python> | ||
| + | names = [" | ||
| + | with cursor.copy(" | ||
| + | for name in names: | ||
| + | copy.write_row((name)) | ||
| + | </ | ||
| + | |||
| + | * name wird hier bei der Übergabe an copy.write_row scheinbar auf tuple gecastet | ||
| + | * allerdings nicht wirklich, es fehlt ein "," | ||
| + | * es muss (name,) heißen, sonst ist es ein String | ||