Ich möchte einige Daten mit INSERTs und UPDATEs modifizieren. Von den psycopg Tutorials sieht es so aus, als müsste ich
%Vor%Psycopgs Cursor-Klasse scheint wenig mit den Cursors zu tun zu haben, wie von postgres .
Wenn ich mein Skript modularisiere, eine Verbindung im Hauptmodul erzeuge und einige Worker-Funktionen (kein Threading, nur für Modularisierung) sollte ich
Übergeben Sie den Verbindungsparameter an die Funktionen und erstellen Sie den Cursor jedes Mal neu. Gibt es einen erheblichen Overhead, der häufig neue Cursorobjekte erzeugt?
%Vor%übergibt Verbindung und Cursor - macht Funktionssignaturen und Implementierung unnötig kompliziert
%Vor% Übergeben Sie nur den Cursor als Parameter und verwenden Sie mycursor.connection.commit()
für das Commit
Jeder der drei wird funktionieren (es ist hauptsächlich eine Frage des persönlichen Geschmacks), aber ich mag besser (1). Hier ist warum:
Der cursor
-Typ ist leichtgewichtig und nur das Erstellen macht nichts Besonderes, abgesehen von der Erstellung eines neuen Python-Objekts. Sie können gerne so viele Cursor erstellen, verwenden (commit / rollback) und zerstören, wie Sie möchten, besonders wenn das hilft, den Code sauber und organisiert zu halten.
Auch cursor
s sind wichtig, wenn Sie mit komplexer Logik arbeiten, die Zugriff auf Daten aus mehreren verschiedenen Abfragen benötigt: In diesem Fall fungiert der Cursor als Halter / Iterator für Ihre Daten.
Am Ende geht es darum, das connection
(Ihr richtiges Handle zum Backend) zu übergeben und die Cursor lokal zu der spezifischen Funktion / Methode zu halten, fühlt sich einfach richtig an.
cursor
s unterstützt das Verwendungsmuster with
, das sie automatisch schließt, sobald der Block fertiggestellt ist. Das kann ein sehr nützliches Muster sein, wenn Sie kompakte Operationen mit den Cursors durchführen.
Zu anderen Zeiten müssen möglicherweise Cursor in einer Funktion verwendet werden, oder mehrere Cursor müssen möglicherweise verwendet werden, und in diesem Fall würde das with
-Muster weniger sinnvoll sein, und es wäre am besten bei Funktion deklariert. Level-Umfang.
Denken Sie auch an die Bedeutung von named cursors
, wo sich Cursor von psycopg und Postgres-Cursor miteinander verflechten. Indem Sie dem Konstruktoraufruf das Attribut name
einen Wert geben, erhalten Sie automatisch einen serverseitigen Cursor, der dann wie jede Python-Sammlung iteriert werden kann und Chunked-Fetches durchführt.
Die Chunk-Größe kann geändert werden, obwohl sie standardmäßig in Blöcken von 2000 abgerufen wird. Dies ist besonders wichtig, wenn Sie große Tabellen abfragen, da Sie mit einem riesigen Ergebnissatz schnell die Speicher-Client-Seite verlassen können. psycopg-Abstracts müssen sich direkt mit Postgres-Cursors befassen, und der nächste Chunk wird bei Bedarf während der Iteration des Cursors transparent abgerufen.
Beachten Sie, dass ein benannter Cursor wirklich nur für eine Sache verwendet werden kann - eine Abfrage, die Sie dann durchlaufen; Wenn Sie versuchen, eine weitere Abfrage für denselben Cursor auszuführen, wird eine Ausnahme ausgelöst, wenn der Speicher bereitgestellt wird. Mit nicht benannten Cursorn können Sie denselben Cursor für die Ausführung verwenden, sobald Sie mit den Ergebnissen fertig sind.
Ich verwende in der Regel benannte Cursor für alle Abfragen, von denen ich denke, dass sie möglicherweise eine große Ergebnismenge zurückgeben können, und nicht benannte Cursor für kleine Abfragen und andere Befehle wie Aktualisierungen, Löschvorgänge, Tabellenerstellung usw.
Die Python-DB-API-Spezifikation lautet:
"Ein Datenbankcursor ... wird verwendet, um den Kontext einer Abrufoperation zu verwalten."
Wenn man die Modularität betrachtet, scheint es, als ob Ihre Funktion die Ergebnisse einer vorherigen Operation benötigt, es sinnvoller wäre, neue Cursor zu erstellen und sie entweder zu schließen oder sie selbst zu schließen, wenn sie den Bereich verlassen. Wenn Sie eine Operation mehrmals wiederholen und sicher sind, dass die Neuerstellung des Cursors Overhead verursacht, können Sie immer eine Hilfsklasse erstellen, die anstelle einer einfachen Hilfsfunktion einen Cursor umschließt.
Allerdings sollten alle drei Methoden gut funktionieren. Ich habe Code mit Stil # 2 geschrieben, obwohl ich zustimme, dass es der schlimmste von ihnen zu sein scheint.
Tags und Links python postgresql psycopg2