Exporter la table Postgres distante vers un fichier CSV sur une machine locale

15

J'ai un accès en lecture seule à une base de données sur un serveur distant. Je peux donc exécuter:

COPY products TO '/tmp/products.csv' DELIMITER ',';

Mais sur ce serveur, je n'ai pas l'autorisation de créer / enregistrer un fichier, je dois donc le faire sur ma machine locale.

Lorsque je me connecte à la base de données distante, comment puis-je exécuter une commande pour enregistrer le fichier sur ma machine locale au lieu du serveur distant?

Ou, comment puis-je exécuter une commande Linux pour se connecter à la base de données distante, exécuter une requête et enregistrer la sortie sous forme de fichier sur ma machine locale?

tasmaniski
la source

Réponses:

29

Les deux approches déjà suggérées semblent être inutilement compliquées.

Utilisez simplement la commande psqlintégrée de \copy, qui fonctionne exactement comme côté serveur COPYmais effectue une copie via le protocole de connexion au client et utilise les chemins d'accès du client.

Parce que c'est une psqlcommande barre oblique inverse, vous omettez le point-virgule de fin, par exemple:

\copy products TO '/tmp/products.csv' CSV DELIMITER ','

Voir l' \copyentrée dans le manuel de la psqlcommande et la documentation de la COPYcommande pour plus de détails.

Tout comme COPYvous pouvez utiliser \copyune (SELECT ...)requête au lieu d'un nom de table lors de la copie des données (mais pas dans).


Une alternative généralement inférieure qui peut être utile dans quelques situations limitées est d'utiliser:

psql -t -P format=unaligned -P fieldsep_zero=on -c 'SELECT * FROM tablename'

et utilisez l' -oindicateur ou la redirection de sortie du shell pour écrire la sortie dans un fichier. Vous devriez presque toujours l'utiliser \copyde préférence.

Craig Ringer
la source
Mais cela ne permet pas les transactions :(
Reza S
Bien sûr que oui. Utilisez un document ici pour alimenter psqlun script, en commençant par BEGIN, puis en faisant vos \copycommandes, puis a COMMIT. Ou utilisez psql -fpour exécuter un script plutôt que d'utiliser un document ici.
Craig Ringer
Merci d'être revenu ... c'est ce que j'ai fini par faire et ça a fonctionné =)
Reza S
Vous pouvez utiliser -Aau lieu de -P format=unalignedet aussi je pense que vous avez besoin d'un-P fieldsep=,
Evan Carroll
2

La commande Linux est:

psql -h 127.0.0.1 -U username -o file.csv -c 'select id, name from clients;'
tasmaniski
la source
1
Cela ne produira pas de CSV, cela produira une sortie de texte formatée. Si vous ajoutiez -t -P format=unaligned à cette commande, vous obtiendrez quelque chose d'un peu plus proche, comme un CSV délimité par un buggy, mais les tuyaux dans le texte ne s'échapperont pas, ce serait donc invalide.
Craig Ringer
Oh, vous voudriez aussi, -P fieldsep=','sauf que cela serait encore plus susceptible de provoquer des erreurs en raison du manque de fuite. -P fieldsep_zero=onserait OK si cela ne vous dérangeait pas d'analyser du texte délimité par des octets nuls, car les octets nuls ne peuvent pas apparaître psqlnaturellement dans la sortie.
Craig Ringer