psql über batch datei ausführen

habe folgendes Problem:

möchte gern aus einer batch datei eine abfrage in eine csv datei per psql kopieren / exportieren. Leider klappt die folgende manuelle Vorgehensweise in die BATCH Datei übersetzt nicht, da die Eingabe aus Pkt. 2) mit einer Fehlermeldung zurückgegebn wird.

funktionierende manuelle Vorgehensweise:

  1. psql -h SERVERNAME -p PORT -U BENUTZER -d DATENBANK

OK für die Anmeldung am Serber und Datenbank

  1. \copy (SELECT TAB.id, TAB.title, TAB.direction FROM parking WHERE TAB.bedingung IS TRUE AND TAB.id::text ~~* ‘%dummy%’::text) to ‘c://TEST//test.csv’ With CSV DELIMITER ‘;’;

OK für das Export

  1. \q

OK für das Verlassen der Datenbank

Versuch Pkt 2) und 3) in einer Zeile zusammenzufassen - ggf. für die BATCH Datei notwendig

psql -h SERVERNAME -p PORT -U BENUTZER -d DATENBANK -c \copy (SELECT TAB.id, TAB.title, TAB.direction FROM parking WHERE TAB.bedingung IS TRUE AND TAB.id::text ~~* ‘%dummy%’::text) to ‘c://TEST//test.csv’ With CSV DELIMITER ‘;’;

bekomme ich die Fehlermeldungen

psql: warning: extra command-line argument “(SELECT” ignored
psql: warning: extra command-line argument “TAB.id” ignored
psql: warning: extra command-line argument “TAB.title” ignored

… ignored
\copy: arguments required

Gibt es ein Zeichen der die Abfrage aus 2) nach dem \copy Befehl für die Option -c zusammenfasst ?
Oder bin ich völlig auf dem falschen Dampfer ?

Danke

Du mußt das passend dann quoten, also das Argument von -c. Es kann bequemer sein, mit -f zu arbeiten und die auszuführenden Befehle in eine extra Datei zu packen und diese eben als Parameter von -f zu verwenden.

TAB.id::text ~~* ‘%dummy%’::text - wenn ich diesen bereich weglasse geht es. es macht %dummy% bei BATCH probleme, weil als Variable gedeutet wird

-f - welchen Teil der Abfrage muss ich in die Option packen ? und wie leite ich diese in die CSV Datei um ?

Du sollst eine Datei erstellen, die Deine Kommandos enthält. Den Namen dieser Datei packst Du hinter -f.

Hint: es gibt auch eine man-page bzw. Online-Hilfe zu psql. Einfach mal mit --help starten, oder ‘man psql’ - wenn man in der glücklichen Lage ist, ein OS zu haben, welches man-pages hat :wink: Und ansonsten gibt es noch die Doku: https://www.postgresql.org/docs/9.6/static/app-psql.html

-mit -f und -o wird eine formatierte Tabelle geschrieben

id | title | direction | xxxx| xxxx
------------------------------------------±-----------------------------------------±-----------------±----------±-----------
xxx | xxx | xxx | 0 | 19

wie kann man eine Datei mit “;” als Separator erzeugen ? auch ohne header ?

xxx;xxx;xxx;0;19

Bei der Hilfe komme ich leider anhand Beispiele mit folgenden Optionen nicht weiter

-F Fieldseparator
oder
\pset [ option [ value ] ]

Moment. Erst einmal RESET und zurück zu Anfang. Da wolltest Du einen Kommandostring übergeben, und ich empfahl Dir, dieses Kommando in eine Datei zu schreiben und die Datei mit -f anzugeben.

Danke, jetzt verstanden. Beides ist nämlich möglich.

Habe jetzt die komplette Abfrage in die Datei mit dem Export Befehl in csv eingesetzt. Jetzt ist nur das problem, dass in der Abfrage Datei keine Variablen funktionieren.

Du kannst mit -v val=wert beim Aufruf von psql Variablen setzen, auf die Variable val kannst Du im Script via :val zugreifen.
Angenommen, Du hast diese Tabelle:

test=# select * from moltiti ;
 id | name  
----+-------
  1 | Heinz
  2 | Egon
(2 Zeilen)

und diese Datei: (my_sql.sql)

select * from moltiti  where id = :my_val;

Dann ergibt:

psql -v my_val=1 -f my_sql.sql test

dies:

 id | name  
----+-------
  1 | Heinz
(1 Zeile)

Andreas

habe jetzt folgenderweise probiert…

–> in die abfrage.sql: variable auf :mypath festgelegt

\copy (SELECT TAB.id, TAB.title, TAB.direction FROM parking WHERE TAB.bedingung IS TRUE AND TAB.id::text ~~* ‘%dummy%’::text) to :mypath With CSV DELIMITER ‘;’;

–> im psql aufruf:

psql -h SERVERNAME -p PORT -U BENUTZER -d DATENBANK -v mypath=’%subdirPD%//%dtStamp%.csv’ -f abfrage.sql

wobei folgende Variablen aus der BATCH Datei übergeben werden
%subdirPD%
%dtStamp%

Fehlermeldung ist psql :mypath: permission denied

entweder Windows-Rechte passen nicht oder das Quoting in der Windows-Batch haut so nicht hin oder … oder … hier gebe ich auf, vielleicht ist ja jemand da, der sich mit Windows auskennt.

danke es waren viele nützliche hinweise, ich probiere es weiter. bin ganz neu in diesem thema, vlt. stelle ich deswegen blöde fragen

jetzt hat es gklappt abfrage anders gestellt und %% statt % gesetzt

Super!

noch eine Frage, wie bekomme ich bei der Abfrage hin, dass die CSV datei nicht in eine Zeile geschrieben wird sondern ein linebreak gemacht wird

also lf to crlf

COPY TO will terminate each row with a Unix-style newline ("\n"). Servers running on Microsoft Windows instead output carriage return/newline ("\r\n"), but only for COPY to a server file; for consistency across platforms, COPY TO STDOUT always sends “\n” regardless of server platform. COPY FROM can handle lines ending with newlines, carriage returns, or carriage return/newlines. To reduce the risk of error due to un-backslashed newlines or carriage returns that were meant as data, COPY FROM will complain if the line endings in the input are not all alike.

https://www.postgresql.org/docs/9.6/static/sql-copy.html

Mach es notfalls später, dafür gibt es geeignete Tools.

sfk176 nutze ich, wollte aber ersparen :wink: