web-dev-qa-db-fra.com

Importation PostgreSQL CSV à partir de la ligne de commande

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.

31
TheLovelySausage

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;"
33
Simo Kivistö

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"
33
Dmitri Zaitsev

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
8
wildplasser

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;"
6
Andrea Araldo