La soluzione nella risposta accettata funzionerà solo sul server e quando l'utente che esegue la query avrà le autorizzazioni per leggere il file come spiegato in questa risposta SO.
Altrimenti, un approccio più flessibile consiste nel sostituire COPY
di SQL comando con psql
"meta-comando" chiamato \copy
che accetta tutte le stesse opzioni della "vera" COPIA, ma viene eseguito all'interno del client (senza bisogno di ;
alla fine):
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
Come da documenti, il \copy
comando:
Esegue una copia frontend (client). Questa è un'operazione che esegue un comando SQL COPY, ma invece del server che legge o scrive il file specificato, psql legge o scrive il file e instrada i dati tra il server e il file system locale. Ciò significa che l'accessibilità e i privilegi dei file sono quelli dell'utente locale, non del server, e non sono richiesti privilegi di superutente SQL.
Inoltre, se the_file.csv
contiene l'intestazione nella prima riga, può essere riconosciuta aggiungendo header
alla fine del comando precedente:
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv header"
Come affermato nella documentazione di PostgreSQL (II. PostgreSQL Client Applications - psql) puoi passare un comando a psql
(terminale interattivo PostgreSQL) con lo switch -c
. Le tue opzioni sono:
1, CSV lato client:\copy
meta-comando
eseguire l'SQL COPY
comando ma il file viene letto sul client e il contenuto instradato al server.
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
(opzione lato client originariamente menzionata in questa risposta)
2. CSV lato server:SQL COPY
comando
legge il file sul server (l'utente corrente deve disporre dei permessi necessari):
psql -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"
i ruoli del database necessari per leggere il file sul server:
COPY
la denominazione di un file o di un comando è consentita solo ai superuser del database o agli utenti a cui è concesso uno dei ruoli predefinitipg_read_server_files
,pg_write_server_files
, opg_execute_server_program
anche il processo del server PostgreSQL deve avere accesso al file.
Il modo più flessibile è usare una shell HERE document
, che ti consente di utilizzare variabili di shell all'interno della tua query, anche tra virgolette (doppie o singole):
#!/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
Per completare la risposta precedente, suggerirei:
psql -d your_dbname --user=db_username -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"