Die Lösung in der akzeptierten Antwort funktioniert nur auf dem Server und wenn der Benutzer, der die Abfrage ausführt, die Berechtigung zum Lesen der Datei hat, wie in dieser SO-Antwort erläutert.
Andernfalls besteht ein flexiblerer Ansatz darin, den COPY
von SQL zu ersetzen Befehl mit dem psql
's "Meta-Befehl" namens \copy
die dieselben Optionen wie die "echte" COPY akzeptiert, aber innerhalb des Clients ausgeführt wird (ohne dass ;
erforderlich ist am Ende):
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
Laut Dokumentation ist der \copy
Befehl:
Führt eine Frontend-(Client-)Kopie durch. Dies ist eine Operation, die einen SQL COPY-Befehl ausführt, aber anstatt dass der Server die angegebene Datei liest oder schreibt, liest oder schreibt psql die Datei und leitet die Daten zwischen dem Server und dem lokalen Dateisystem weiter. Das bedeutet, dass die Dateizugriffsrechte und -privilegien die des lokalen Benutzers sind, nicht die des Servers, und dass keine SQL-Superuser-Privilegien erforderlich sind.
Wenn außerdem the_file.csv
enthält in der ersten Zeile den Header, erkennbar am Zusatz header
am Ende des obigen Befehls:
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv header"
Wie in der PostgreSQL-Dokumentation (II. PostgreSQL-Clientanwendungen - psql) angegeben, können Sie einen Befehl an psql
übergeben (interaktives PostgreSQL-Terminal) mit dem Schalter -c
. Ihre Optionen sind:
1, clientseitige CSV:\copy
Meta-Befehl
führen Sie die SQL COPY
aus Befehl, aber die Datei wird auf dem Client gelesen und der Inhalt an den Server weitergeleitet.
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
(clientseitige Option, die ursprünglich in dieser Antwort erwähnt wurde)
2. Serverseitiges CSV:SQL COPY
Befehl
liest die Datei auf dem Server (der aktuelle Benutzer muss die erforderlichen Berechtigungen haben):
psql -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"
die DB-Rollen, die zum Lesen der Datei auf dem Server benötigt werden:
COPY
Das Benennen einer Datei oder eines Befehls ist nur Datenbank-Superusers oder Benutzern gestattet, denen eine der Standardrollenpg_read_server_files
gewährt wurde , pg_write_server_files
, oderpg_execute_server_program
auch der PostgreSQL-Serverprozess muss Zugriff auf die Datei haben.
Der flexibelste Weg ist die Verwendung einer Shell HERE document
, wodurch Sie Shell-Variablen in Ihrer Abfrage verwenden können, sogar innerhalb (doppelter oder einfacher) Anführungszeichen:
#!/bin/sh
THE_USER=moi
THE_DB=stuff
THE_TABLE=personnel
PSQL=/opt/postgresql/bin/psql
THE_DIR=/tmp
THE_FILE=the_file.csv
${PSQL} -U ${THE_USER} ${THE_DB} <<OMG
COPY ${THE_TABLE} FROM '${THE_DIR}/${THE_FILE}' delimiter '|' csv;
OMG
Um die vorherige Antwort zu vervollständigen, würde ich vorschlagen:
psql -d your_dbname --user=db_username -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"