Benutzer-Werkzeuge

Webseiten-Werkzeuge


python:psycopg

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

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;
 +</sxh>
 +
 +  * "on commit" definiert was bei einem Commit mit der Tabelle passieren soll
 +      * 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" -> alles oder nichts
 +      * 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("copy table_name (column1, column2) from stdin") as copy:
 +        for record in records:
 +            copy.write_row(record)
 +</sxh>
 +  * 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("copy table_name (column1, column2) to stdout") as copy:
 +        for record in copy.rows():
 +            Some action
 +</sxh>
 +
 +<code>
 +Traceback (most recent call last):
 +  File "mytest.py", line 24, in <module>
 +    copy.write_row(word)
 +  File "/usr/lib/python3.8/contextlib.py", line 120, in __exit__
 +    next(self.gen)
 +  File "usr/share/virtualenvs/noise3-IfVx2oqf/lib/python3.8/site-packages/psycopg/cursor.py", line 902, in copy
 +    raise ex.with_traceback(None)
 +psycopg.errors.BadCopyFileFormat: extra data after last expected column
 +CONTEXT:  COPY personen, line 1: "H a n s"
 +</code>
 +
 +^ Hier wurde vergessen das der Datensatz für die Spalte ein Iterateable sein muss. \\
 +Daher wurde "Getting" nicht als String, sondern als Sequenz betrachtet und versucht in mehr Spalten einzufügen als vorhanden sind.
 +
 +Fehlschlagender Code (Beispiel):
 +
 +<sxh python>
 +names = ["Hans", "Peter", "Dieter"]
 +with cursor.copy("copy personen (vorname) from stdin") as copy:
 +    for name in names:
 +        copy.write_row(name)
 +</sxh>
 +
 +  * 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 = ["Hans", "Peter", "Dieter"]
 +with cursor.copy("copy personen (vorname) from stdin") as copy:
 +    for name in names:
 +        copy.write_row((name))
 +</sxh>
 +
 +  * 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
python/psycopg.1688154266.txt.gz · Zuletzt geändert: 2023/06/30 21:44 von root