La solución en la respuesta aceptada solo funcionará en el servidor y cuando el usuario ejecute la consulta tendrá permisos para leer el archivo como se explica en esta respuesta SO.
De lo contrario, un enfoque más flexible es reemplazar el COPY
de SQL. comando con el psql
El "meta-comando" llamado \copy
que toma todas las mismas opciones que la COPIA "real", pero se ejecuta dentro del cliente (sin necesidad de ;
al final):
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
Según los documentos, el \copy
comando:
Realiza una copia de frontend (cliente). Esta es una operación que ejecuta un comando SQL COPY, pero en lugar de que el servidor lea o escriba el archivo especificado, psql lee o escribe el archivo y enruta los datos entre el servidor y el sistema de archivos local. Esto significa que la accesibilidad y los privilegios de los archivos son los del usuario local, no los del servidor, y no se requieren privilegios de superusuario de SQL.
Además, si el the_file.csv
contiene el encabezado en la primera línea, se puede reconocer agregando header
al final del comando anterior:
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv header"
Como se indica en la documentación de PostgreSQL (II. Aplicaciones cliente de PostgreSQL - psql), puede pasar un comando a psql
(Terminal interactivo de PostgreSQL) con el interruptor -c
. Sus opciones son:
1, CSV del lado del cliente:\copy
metacomando
realizar el SQL COPY
pero el archivo se lee en el cliente y el contenido se enruta al servidor.
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
(opción del lado del cliente mencionada originalmente en esta respuesta)
2. CSV del lado del servidor:SQL COPY
comando
lee el archivo en el servidor (el usuario actual debe tener los permisos necesarios):
psql -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"
los roles de base de datos necesarios para leer el archivo en el servidor:
COPY
Solo se permite nombrar un archivo o comando a los superusuarios de la base de datos o a los usuarios que tienen uno de los roles predeterminadospg_read_server_files
, pg_write_server_files
, o pg_execute_server_program
también el proceso del servidor PostgreSQL necesita tener acceso al archivo.
La forma más flexible es usar un shell HERE document
, que le permite usar variables de shell dentro de su consulta, incluso dentro de comillas (dobles o simples):
#!/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
Para completar la respuesta anterior, sugeriría:
psql -d your_dbname --user=db_username -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"