PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Speichern Sie die PL/pgSQL-Ausgabe von PostgreSQL in einer CSV-Datei

Möchten Sie die resultierende Datei auf dem Server oder auf dem Client?

Serverseite

Wenn Sie möchten, dass etwas einfach wiederverwendet oder automatisiert werden kann, können Sie den integrierten COPY-Befehl von Postgresql verwenden. z. B.

Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;

Dieser Ansatz läuft vollständig auf dem Remote-Server - Es kann nicht auf Ihren lokalen PC schreiben. Es muss auch als Postgres-„Superuser“ (normalerweise „root“ genannt) ausgeführt werden, da Postgres es nicht daran hindern kann, mit dem lokalen Dateisystem dieser Maschine böse Dinge zu tun.

Das bedeutet nicht unbedingt, dass Sie als Superuser angemeldet sein müssen (das zu automatisieren wäre ein Sicherheitsrisiko anderer Art), denn Sie können den SECURITY DEFINER verwenden Option zu CREATE FUNCTION um eine Funktion zu erstellen, die so läuft, als ob Sie ein Superuser wären .

Der entscheidende Teil ist, dass Ihre Funktion dazu da ist, zusätzliche Überprüfungen durchzuführen und nicht nur die Sicherheit zu umgehen. Sie könnten also eine Funktion schreiben, die genau die Daten exportiert, die Sie benötigen, oder Sie könnten etwas schreiben, das verschiedene Optionen akzeptiert, solange sie erfüllen eine strenge Whitelist. Sie müssen zwei Dinge überprüfen:

  1. Welche Dateien Soll der Benutzer auf der Festplatte lesen/schreiben dürfen? Das kann zum Beispiel ein bestimmtes Verzeichnis sein, und der Dateiname muss ein passendes Präfix oder eine Erweiterung haben.
  2. Welche Tabellen Soll der Benutzer in der Datenbank lesen/schreiben können? Dies würde normalerweise durch GRANT definiert werden s in der Datenbank, aber die Funktion wird jetzt als Superuser ausgeführt, sodass Tabellen, die normalerweise "außerhalb der Grenzen" liegen, vollständig zugänglich sind. Sie möchten wahrscheinlich nicht zulassen, dass jemand Ihre Funktion aufruft und Zeilen am Ende Ihrer „Benutzer“-Tabelle hinzufügt …

Ich habe einen Blogbeitrag geschrieben, der diesen Ansatz erweitert und einige Beispiele für Funktionen enthält, die Dateien und Tabellen exportieren (oder importieren), die strenge Bedingungen erfüllen.

Clientseite

Der andere Ansatz besteht darin, die Dateiverwaltung auf der Clientseite vorzunehmen , d. h. in Ihrer Anwendung oder Ihrem Skript. Der Postgres-Server muss nicht wissen, in welche Datei Sie kopieren, er spuckt die Daten einfach aus und der Client legt sie irgendwo ab.

Die zugrunde liegende Syntax dafür ist COPY TO STDOUT Befehl, und grafische Tools wie pgAdmin werden es für Sie in einen netten Dialog verpacken.

Die psql Befehlszeilen-Client hat einen speziellen "Meta-Befehl" namens \copy , das dieselben Optionen wie das "echte" COPY akzeptiert , wird aber innerhalb des Clients ausgeführt:

\copy (Select * From foo) To '/tmp/test.csv' With CSV

Beachten Sie, dass es kein abschließendes ; gibt , da Meta-Befehle im Gegensatz zu SQL-Befehlen durch Zeilenumbrüche abgeschlossen werden.

Aus der Dokumentation:

Verwechseln Sie COPY nicht mit der psql-Anweisung \copy. \copy ruft COPY FROM STDIN oder COPY TO STDOUT auf und ruft/speichert dann die Daten in einer Datei, auf die der psql-Client zugreifen kann. Daher hängen Dateizugänglichkeit und Zugriffsrechte eher vom Client als vom Server ab, wenn \copy verwendet wird.

Ihre Anwendungsprogrammiersprache kann haben auch Unterstützung für das Pushen oder Abrufen der Daten, aber Sie können COPY FROM STDIN im Allgemeinen nicht verwenden /TO STDOUT innerhalb einer Standard-SQL-Anweisung, da es keine Möglichkeit gibt, den Ein-/Ausgabestrom zu verbinden. Der PostgreSQL-Handler von PHP (nicht PDO) beinhaltet sehr einfaches pg_copy_from und pg_copy_to Funktionen, die zu/von einem PHP-Array kopieren, was für große Datenmengen möglicherweise nicht effizient ist.