ich möchte per Linux-Konsole eine *.csv-Datei in eine Postgres-Datenbank importieren, die auf einem entfernten Server liegt. Gibt es dafür irgendeine Möglichkeit? Oder geht das nur, in dem ich mich per SSH mit dem Server verbinde und das ganze dort über die Postgres-Konsole mache?
Zum reinen Import der *.csv-Datei wäre ich wohl beim COPY-Befehl richtig, aber mein Problem dabei ist, dass ich eben nicht lokal auf der Kiste bin.
Ja, an COPY habe ich auch gedacht. Aber das kann ich doch m.E. nur benutzen, wenn ich in der Postgres-Konsole eingeloggt bin, oder? Mein Problem ist, dass ich das csv, das bei mir lokal liegt, bei einem entfernten Server einspielen möchte.
Eine Möglichkeit wäre natürlich das csv auf den Server zu kopieren, per SSH drauf zu gehen, mich in die psql-Konsole einzuloggen und das file dann per COPY einzuspielen. Da das ganze aber nicht nur eine einmalige Sache ist, sondern regelmäßig erfolgen soll, würde ich gerne vermeiden, dass ich mich extra per SSH verbinden muss und die Datei zuerst rüberkopieren muss.
Was akretschmer dir - etwas umständlich - sagen möchte: du kannst bei COPY auch FROM STDIN nutzen und damit Daten über das Netzwerk kopieren.
Alternativ kannst du die Daten auch unix-typisch pipen, zum Beispiel über “netcat”.
Hihi, da antworte ich mal lieber wieder bevor ihr euch an die Gurgel geht
Ja, der Kern des Problems ist wohl wirklich, dass ich das ganze übers Netzwerk machen möchte und nicht lokal. Hätte ich vielleicht im Topic erwähnen sollen…
Hier meine zwei Ansätze:
“Naiver Ansatz” ohne netcat
echo "COPY mytable FROM 'mycsv.csv' WITH CSV DELIMITER AS ';'" | psql -h 192.168.0.3 --dbname mydb -U postgres --password
Problem: Ich bekomme die Meldung “psql: FATAL: database “mydb” does not exist”. Da sie aber 100%ig auf dem entfernten Server existiert (nicht aber bei mir lokal) vermute ich, dass an dem Ansatz grundsätzlich was nicht passt…
Netcat
Ddamit hab ich ehrlich gesagt noch nie gearbeitet und ich hab auch nicht verstanden, wie ich das hier einsetzen sollte…statt dem “echo” vielleicht?
Netcat bildet einen Transportlayer über das Netzwerk.
Du startest das auf beiden Seiten und das transportiert dir die da hineingeschriebenen Daten (also deine Datei) von einem Rechner zum anderen.
Der Vorteil ist, das am anderen Ende vom empfangendem netcat einfach ein psql mit “FROM STDIN” sitzen kann. Du musst die Datei also nicht mehr lokal irgendwo zwischenspeichern.
Alles, was man braucht, ist ein lokales psql. Dann reicht:
[root@web45 ~]# # bin auf system web45, db läuft auf system sql9
[root@web45 ~]# # hier meine lokale csv - Datei:
[root@web45 ~]# cat foo.csv
1,eins
2,zwei
3,drei
[root@web45 ~]# # nun kopiere ich das via meinem lokalen psql in die entfernte Datenbank
[root@web45 ~]# psql -h sql9 -U kretschmer test -c "copy test.foo from stdin delimiter ','" < foo.csv
[root@web45 ~]# # das war es dann auch schon
[root@web45 ~]#
@ads:
Vielen Dank für die Info! Ich werde es jedoch zunächst mal mit dem Ansatz ohne netcat versuchen.
@akretschmer:
Seltsam, jetzt habe ich es genauso gemacht wie Du, bekomme aber trotzdem wieder die gleiche Fehlermeldung wie vorher:
root@host1:/home/hannes/Desktop/test# psql -h host2 -U postgres mydb -c "copy mydb.mytable from stdin delimiter ';'" < temp.csv
Passwort für Benutzer postgres:
psql: FATAL: database "mydb" does not exist
Die Datenbank mydb existiert wie gesagt lokal nicht (host1), aber auf dem Server (host2) schon.
P.S.:
Ich finde es wirklich super, wie ihr beide euch hier im Forum engagiert! Ich habe von euch schon so viele weiterhelfende Beiträge gelesen und bin immer wieder überrascht von euerem Postgres-Knowhowr! Mir ist durchaus klar, dass das viel Zeit in Anspruch nimmt und sicher oft Nerven kostet Deshalb halte ich es zumindest mal für angebracht, mal ein großes Lob zu äußern
Zu Deinem Problem: ich könnte mir jetzt nur noch vorstellen, daß die DB vielleicht “MyDB” oder “MYDB” oder “myDB” oder “Mydb” oder … heißt, nicht aber “mydb”.