J'utilise le terminal psql Postgres pour importer des fichiers CSV dans des tableaux à l'aide des éléments suivants
COPY tbname FROM
'/tmp/the_file.csv'
delimiter '|' csv;
ce qui fonctionne bien sauf que je dois être connecté au terminal psql pour l'exécuter.
Je voudrais savoir si quelqu'un connaît un moyen de faire une commande similaire à celle-ci depuis la ligne de commande Linux Shell similaire à la façon dont Postgres autorise une commande Shell comme ci-dessous
/opt/postgresql/bin/pg_dump dbname > /tmp/dbname.sql
Cela permet de vider une base de données du Linux Shell sans être connecté au terminal psql.
Comme indiqué dans la documentation PostgreSQL ( II. PostgreSQL Client Applications - psql ), vous pouvez passer une commande à psql
avec le commutateur -c
:
psql -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"
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 this SO answer .
Sinon, une approche plus flexible consiste à remplacer la commande COPY
de SQL par la "méta-commande" de psql
appelée \copy
qui qui prend toutes les mêmes options que la "vraie" COPIE, mais qui est exécutée à l'intérieur du client (sans besoin de ;
à la fin):
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
Selon les documents , 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é et les privilèges des fichiers sont ceux de l'utilisateur local et non du serveur et qu'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"
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 précédente réponse , je suggère:
psql -d your_dbname --user=db_username -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"