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:
- 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.
- 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.