it-swarm.com.de

Der Befehl postgres client copy (\ copy) hat keinen Zugriff auf eine temporäre Tabelle?

Ich generiere eine Liste von SQL-Befehlen, um einige Daten zu exportieren, die ich letztendlich mit psql -f ausführe. Die Abfragen erhalten alle dieselbe Teilmenge von Daten, daher dachte ich, ich würde die Qualifikationen herausrechnen und eine Liste der zulässigen Benutzer-IDs in eine temporäre Tabelle wie diese einfügen

create temporary table tmp_export_users as (select id from users where ...)

dann verweise darauf in meinen\copy Befehlen wie

\copy (select ... from table where user_id in (select id from tmp_export_users)) TO 'filename.csv' WITH CSV HEADER

Diese befinden sich alle in derselben Datei, eine pro Zeile, und führen sie aus. Wenn ich die Fehlermeldung erhalte, dass die Kopierbefehle die temporäre Tabelle nicht sehen können, schätze ich, dass der Client-Kopierbefehl nicht dieselben Postgres verwenden darf Sitzung als psql.

Ist das korrekt? Gibt es eine Möglichkeit, dieses Verhalten zu ändern?

8
jkebinger

\copy kann eine temporäre Tabelle verwenden.

Zuerst habe ich dies mit Version 9.0 in der Kommandozeile getestet und bestätigt.
Dann habe ich eine Datei mit dem SQL- und psql-Meta-Befehl \copy Unter Verwendung mehrerer temporärer Tabellen erstellt. Das hat auch bei mir funktioniert.

CREATE TEMP TABLE tmp as SELECT * FROM tbl;
\copy (SELECT * FROM tmp JOIN tbl USING (id)) TO '/var/lib/postgres/test1.csv';

Anruf:

psql -p5432 mydb -f test.sql

Beachten Sie das abschließende Semikolon, das am Ende einer Datei optional ist (implizit beendet), aber nach jeder anderen SQL-Anweisung und auch nach der letzten erforderlich ist, wenn es in psql interaktiv ausgeführt wird.

Normalerweise können psql-Meta-Befehle nicht mit SQL in derselben Zeile gemischt werden in einer Datei ausgeführt nach psql -f. Ich zitiere das Handbuch auf psql :

Das Parsen nach Argumenten endet am Ende der Zeile oder wenn ein anderer nicht zitierter Backslash gefunden wird. Ein nicht zitierter Backslash wird als Beginn eines neuen Meta-Befehls verwendet. Die spezielle Sequenz \\ (Zwei Backslashes) markiert das Ende der Argumente und setzt das Parsen von SQL-Befehlen fort, falls vorhanden. Auf diese Weise können SQL- und psql-Befehle in einer Zeile frei gemischt werden. In jedem Fall können die Argumente eines Meta-Befehls jedoch nicht über das Zeilenende hinaus fortgesetzt werden.

Es gelten jedoch andere Regeln after\copy. Im Wesentlichen wechselt psql nach \copy Automatisch in den SQL-Modus zurück. Siehe:

Aber Sie haben geschrieben, Sie hätten alle Befehle in getrennten Zeilen. Das kann in Ihrem Fall also nicht die Erklärung sein.


Abgesehen davon haben Sie darüber nachgedacht, COPY (den SQL-Befehl ) anstelle von \copy (der psql meta-befehl )?

Natürlich müsste die Zieldatei lokal auf dem Server sein, in diesem Fall nicht auf dem Client. Es gelten unterschiedliche Dateiberechtigungen. Das Handbuch :

Dateien, die in einem COPY -Befehl benannt sind, werden direkt vom Server gelesen oder geschrieben, nicht von der Clientanwendung. Daher müssen sie sich auf dem Datenbankserver befinden und für diesen zugänglich sein, nicht auf dem Client. Sie müssen für den PostgreSQL-Benutzer (die Benutzer-ID, unter der der Server ausgeführt wird) und nicht für den Client zugänglich und lesbar oder beschreibbar sein.

16