La solution dans la réponse acceptée ne fonctionnera que sur le serveur et lorsque l'utilisateur exécutant la requête aura les autorisations pour lire le fichier, comme expliqué dans cette réponse SO.
Sinon, une approche plus flexible consiste à remplacer le COPY
du SQL commande avec le psql
la "méta-commande" appelée \copy
qui prend toutes les mêmes options que le "vrai" COPY, mais est exécuté à l'intérieur du client (sans avoir besoin de ;
à la fin):
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
Selon les docs, le \copy
commande :
Effectue une copie frontale (client). Il s'agit d'une opération qui exécute une commande SQL COPY, mais au lieu que le serveur lise ou écrive le fichier spécifié, psql lit ou écrit le fichier et achemine les données entre le serveur et le système de fichiers local. Cela signifie que l'accessibilité des fichiers et les privilèges sont ceux de l'utilisateur local, et non du serveur, et aucun privilège de superutilisateur SQL n'est requis.
De plus, si le the_file.csv
contient l'en-tête dans la première ligne, il peut être reconnu en ajoutant header
à la fin de la commande ci-dessus :
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv header"
Comme indiqué dans The PostgreSQL Documentation (II. PostgreSQL Client Applications - psql), vous pouvez passer une commande à psql
(terminal interactif PostgreSQL) avec le commutateur -c
. Vos options sont :
1, CSV côté client :\copy
méta-commande
effectuer le SQL COPY
mais le fichier est lu sur le client et le contenu acheminé vers le serveur.
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
(option côté client mentionnée à l'origine dans cette réponse)
2. CSV côté serveur :SQL COPY
commande
lit le fichier sur le serveur (l'utilisateur actuel doit avoir les autorisations nécessaires) :
psql -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"
les rôles DB nécessaires à la lecture du fichier sur le serveur :
COPY
nommer un fichier ou une commande n'est autorisé qu'aux superutilisateurs de la base de données ou aux utilisateurs qui se voient attribuer l'un des rôles par défautpg_read_server_files
,pg_write_server_files
, oupg_execute_server_program
le processus du serveur PostgreSQL doit également avoir accès au fichier.
La manière la plus flexible est d'utiliser un shell HERE document
, qui vous permet d'utiliser des variables shell dans votre requête, même entre guillemets (doubles ou 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
Pour compléter la réponse précédente, je suggérerais :
psql -d your_dbname --user=db_username -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"