Réponses:
Voulez-vous le fichier résultant sur le serveur ou sur le client?
Si vous voulez quelque chose de facile à réutiliser ou à automatiser, vous pouvez utiliser la commande COPY intégrée de Postgresql . par exemple
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
Cette approche s'exécute entièrement sur le serveur distant - elle ne peut pas écrire sur votre PC local. Il doit également être exécuté en tant que "superutilisateur" Postgres (normalement appelé "root") car Postgres ne peut pas l'empêcher de faire des choses désagréables avec le système de fichiers local de cette machine.
Cela ne signifie pas que vous devez être connecté en tant que superutilisateur (l'automatisation serait un risque de sécurité d'un autre type), car vous pouvez utiliser l' SECURITY DEFINER
optionCREATE FUNCTION
pour créer une fonction qui fonctionne comme si vous étiez un superutilisateur .
La partie cruciale est que votre fonction est là pour effectuer des vérifications supplémentaires, pas seulement contourner la sécurité - vous pouvez donc écrire une fonction qui exporte les données exactes dont vous avez besoin, ou vous pouvez écrire quelque chose qui peut accepter diverses options tant qu'elles rencontrer une liste blanche stricte. Vous devez vérifier deux choses:
GRANT
s dans la base de données, mais la fonction s'exécute maintenant en tant que superutilisateur, donc les tables qui seraient normalement "hors limites" seront entièrement accessibles. Vous ne voulez probablement pas laisser quelqu'un invoquer votre fonction et ajouter des lignes à la fin de votre table «utilisateurs»…J'ai écrit un article de blog développant cette approche , y compris quelques exemples de fonctions qui exportent (ou importent) des fichiers et des tables répondant à des conditions strictes.
L'autre approche consiste à gérer le fichier côté client , c'est-à-dire dans votre application ou script. Le serveur Postgres n'a pas besoin de savoir dans quel fichier vous copiez, il crache simplement les données et le client les place quelque part.
La syntaxe sous-jacente pour cela est la COPY TO STDOUT
commande, et des outils graphiques comme pgAdmin l'envelopperont pour vous dans une belle boîte de dialogue.
Le psql
client en ligne de commande a une "méta-commande" spéciale appelée \copy
, qui prend toutes les mêmes options que la "vraie" COPY
, mais est exécutée à l'intérieur du client:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
Notez qu'il n'y a pas de terminaison ;
, car les méta-commandes sont terminées par une nouvelle ligne, contrairement aux commandes SQL.
De la documentation :
Ne confondez pas COPY avec l'instruction \ copy psql. \ copy appelle COPY FROM STDIN ou COPY TO STDOUT, puis récupère / stocke les données dans un fichier accessible au client psql. Ainsi, l'accessibilité des fichiers et les droits d'accès dépendent du client plutôt que du serveur lorsque \ copy est utilisé.
Votre langage de programmation d'application peut également prendre en charge la transmission ou la récupération des données, mais vous ne pouvez généralement pas utiliser COPY FROM STDIN
/ TO STDOUT
dans une instruction SQL standard, car il n'y a aucun moyen de connecter le flux d'entrée / sortie. Le gestionnaire PostgreSQL de PHP ( pas PDO) comprend des fonctions très basiques pg_copy_from
et pg_copy_to
qui copient vers / depuis un tableau PHP, ce qui peut ne pas être efficace pour les grands ensembles de données.
\copy
fonctionne aussi - là, les chemins sont relatifs au client, et aucun point-virgule n'est nécessaire / autorisé. Voir mon montage.
\copy
soit une doublure. Donc, vous n'avez pas la beauté de formater le sql comme vous le souhaitez, et de simplement mettre une copie / fonction autour de lui.
\copy
est une méta-commande spéciale dans le psql
client de ligne de commande . Cela ne fonctionnera pas dans d'autres clients, comme pgAdmin; ils auront probablement leurs propres outils, tels que des assistants graphiques, pour faire ce travail.
Il existe plusieurs solutions:
psql
commandepsql -d dbname -t -A -F"," -c "select * from users" > output.csv
Cela a le gros avantage que vous pouvez l'utiliser via SSH, comme ssh postgres@host command
- vous permettant d'obtenir
copy
commandes postgresCOPY (SELECT * from users) To '/tmp/output.csv' With CSV;
>psql dbname
psql>\f ','
psql>\a
psql>\o '/tmp/output.csv'
psql>SELECT * from users;
psql>\q
Tous peuvent être utilisés dans des scripts, mais je préfère le n ° 1.
Dans le terminal (lorsqu'il est connecté à la base de données), définissez la sortie dans le fichier cvs
1) Réglez le séparateur de champ sur ','
:
\f ','
2) Définissez le format de sortie non aligné:
\a
3) Afficher uniquement les tuples:
\t
4) Réglez la sortie:
\o '/tmp/yourOutputFile.csv'
5) Exécutez votre requête:
:select * from YOUR_TABLE
6) Sortie:
\o
Vous pourrez alors retrouver votre fichier csv à cet emplacement:
cd /tmp
Copiez-le en utilisant la scp
commande ou éditez en utilisant nano:
nano /tmp/yourOutputFile.csv
COPY
ou \copy
gèrent correctement (conversion au format CSV standard); est ce que ca?
Si vous êtes intéressé par toutes les colonnes d'un tableau particulier avec les en-têtes, vous pouvez utiliser
COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
C'est un tout petit peu plus simple que
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
qui, à ma connaissance, sont équivalentes.
Cette information n'est pas vraiment bien représentée. Comme c'est la deuxième fois que j'ai besoin de dériver ceci, je mettrai ceci ici pour me rappeler si rien d'autre.
Vraiment, la meilleure façon de le faire (retirer CSV des postgres) est d'utiliser la COPY ... TO STDOUT
commande. Bien que vous ne souhaitiez pas le faire de la manière indiquée dans les réponses ici. La bonne façon d'utiliser la commande est:
COPY (select id, name from groups) TO STDOUT WITH CSV HEADER
C'est génial pour une utilisation sur ssh:
$ ssh psqlserver.example.com 'psql -d mydb "COPY (select id, name from groups) TO STDOUT WITH CSV HEADER"' > groups.csv
C'est génial pour une utilisation à l'intérieur de docker sur ssh:
$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
C'est même génial sur la machine locale:
$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
Ou dans Docker sur la machine locale?:
docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
Ou sur un cluster kubernetes, en docker, sur HTTPS ??:
kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
Tellement polyvalent, beaucoup de virgules!
Oui je l'ai fait, voici mes notes:
L'utilisation /copy
exécute efficacement les opérations sur les fichiers sur le système psql
sur lequel la commande est exécutée, en tant qu'utilisateur qui l'exécute 1 . Si vous vous connectez à un serveur distant, il est simple de copier des fichiers de données sur le système s'exécutant psql
vers / depuis le serveur distant.
COPY
exécute les opérations de fichiers sur le serveur en tant que compte utilisateur du processus d'arrière-plan (par défaut postgres
), les chemins d'accès aux fichiers et les autorisations sont vérifiés et appliqués en conséquence. Si vous utilisez, TO STDOUT
les vérifications des autorisations de fichiers sont ignorées.
Ces deux options nécessitent un déplacement de fichier ultérieur si elles psql
ne s'exécutent pas sur le système sur lequel vous souhaitez que le CSV résultant réside finalement. C'est le cas le plus probable, selon mon expérience, lorsque vous travaillez principalement avec des serveurs distants.
Il est plus complexe de configurer quelque chose comme un tunnel TCP / IP sur ssh vers un système distant pour une sortie CSV simple, mais pour d'autres formats de sortie (binaire), il peut être préférable de passer /copy
par une connexion tunnelée, en exécutant un local psql
. Dans la même veine, pour les importations importantes, déplacer le fichier source vers le serveur et l'utiliser COPY
est probablement l'option la plus performante.
Avec les paramètres psql, vous pouvez formater la sortie comme CSV mais il y a des inconvénients comme devoir se rappeler de désactiver le pageur et de ne pas obtenir d'en-têtes:
$ psql -P pager=off -d mydb -t -A -F',' -c 'select * from groups;'
2,Technician,Test 2,,,t,,0,,
3,Truck,1,2017-10-02,,t,,0,,
4,Truck,2,2017-10-02,,t,,0,,
Non, je veux juste retirer CSV de mon serveur sans compiler et / ou installer un outil.
psql
peut le faire pour vous:
edd@ron:~$ psql -d beancounter -t -A -F"," \
-c "select date, symbol, day_close " \
"from stockprices where symbol like 'I%' " \
"and date >= '2009-10-02'"
2009-10-02,IBM,119.02
2009-10-02,IEF,92.77
2009-10-02,IEV,37.05
2009-10-02,IJH,66.18
2009-10-02,IJR,50.33
2009-10-02,ILF,42.24
2009-10-02,INTC,18.97
2009-10-02,IP,21.39
edd@ron:~$
Voir man psql
pour obtenir de l'aide sur les options utilisées ici.
La nouvelle version - psql 12 - prendra en charge --csv
.
--csv
Bascule en mode de sortie CSV (Comma-Separated Values). C'est équivalent au format \ pset csv .
csv_fieldsep
Spécifie le séparateur de champ à utiliser au format de sortie CSV. Si le caractère de séparation apparaît dans la valeur d'un champ, ce champ est sorti entre guillemets doubles, conformément aux règles CSV standard. La valeur par défaut est une virgule.
Usage:
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv postgres
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv -P csv_fieldsep='^' postgres
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv postgres > output.csv
Je travaille sur AWS Redshift, qui ne prend pas en charge la COPY TO
fonctionnalité.
Mon outil de BI prend cependant en charge les CSV délimités par des tabulations, j'ai donc utilisé les éléments suivants:
psql -h dblocation -p port -U user -d dbname -F $'\t' --no-align -c "SELECT * FROM TABLE" > outfile.csv
Dans pgAdmin III, il existe une option pour exporter vers un fichier à partir de la fenêtre de requête. Dans le menu principal, c'est Query -> Execute to file ou il y a un bouton qui fait la même chose (c'est un triangle vert avec une disquette bleue par opposition au triangle vert uni qui exécute simplement la requête). Si vous n'exécutez pas la requête à partir de la fenêtre de requête, je ferais ce que IMSoP a suggéré et j'utiliserais la commande de copie.
J'ai écrit un petit outil appelé psql2csv
qui encapsule le COPY query TO STDOUT
motif, résultant en un CSV correct. Son interface est similaire à psql
.
psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY
La requête est supposée être le contenu de STDIN, s'il est présent, ou le dernier argument. Tous les autres arguments sont transmis à psql à l'exception de ceux-ci:
-h, --help show help, then exit
--encoding=ENCODING use a different encoding than UTF8 (Excel likes LATIN1)
--no-header do not output a header
Si vous avez une requête plus longue et que vous aimez utiliser psql, placez votre requête dans un fichier et utilisez la commande suivante:
psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv
-F","
au lieu de -F";"
générer un fichier CSV qui s'ouvrirait correctement dans MS Excel
Je recommande fortement DataGrip , un IDE de base de données de JetBrains. Vous pouvez exporter une requête SQL vers un fichier CSV et configurer facilement le tunneling ssh. Lorsque la documentation fait référence à "jeu de résultats", cela signifie le résultat renvoyé par une requête SQL dans la console.
Je ne suis pas associé à DataGrip, j'adore le produit!
JackDB , un client de base de données dans votre navigateur Web, rend cela très simple. Surtout si vous êtes sur Heroku.
Il vous permet de vous connecter à des bases de données distantes et d'exécuter des requêtes SQL sur celles-ci.
Source
(source: jackdb.com )
Une fois votre base de données connectée, vous pouvez exécuter une requête et exporter vers CSV ou TXT (voir en bas à droite).
Remarque: je ne suis en aucun cas affilié à JackDB. J'utilise actuellement leurs services gratuits et je pense que c'est un excellent produit.
À la demande de @ skeller88, je republie mon commentaire en tant que réponse afin qu'il ne soit pas perdu par les personnes qui ne lisent pas chaque réponse ...
Le problème avec DataGrip est qu'il met une poignée sur votre portefeuille. Ce n'est pas gratuit. Essayez l'édition communautaire de DBeaver sur dbeaver.io. Il s'agit d'un outil de base de données multiplateforme FOSS pour les programmeurs SQL, les administrateurs de bases de données et les analystes qui prend en charge toutes les bases de données populaires: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto, etc.
DBeaver Community Edition simplifie la connexion à une base de données, émet des requêtes pour récupérer des données, puis télécharge l'ensemble de résultats pour l'enregistrer au format CSV, JSON, SQL ou d'autres formats de données courants. Il s'agit d'un concurrent FOSS viable pour TOAD pour Postgres, TOAD pour SQL Server ou Toad pour Oracle.
Je n'ai aucune affiliation avec DBeaver. J'aime le prix et les fonctionnalités, mais j'aimerais qu'ils ouvrent davantage l'application DBeaver / Eclipse et facilitent l'ajout de widgets d'analyse à DBeaver / Eclipse, plutôt que d'exiger des utilisateurs de payer l'abonnement annuel pour créer des graphiques et des graphiques directement dans L'application. Mes compétences en codage Java sont rouillées et je n'ai pas envie de prendre des semaines pour réapprendre à créer des widgets Eclipse, seulement pour découvrir que DBeaver a désactivé la possibilité d'ajouter des widgets tiers à DBeaver Community Edition.
Les utilisateurs de DBeaver ont-ils une idée des étapes à suivre pour créer des widgets d'analyse à ajouter à l'édition communautaire de DBeaver?
import json
cursor = conn.cursor()
qry = """ SELECT details FROM test_csvfile """
cursor.execute(qry)
rows = cursor.fetchall()
value = json.dumps(rows)
with open("/home/asha/Desktop/Income_output.json","w+") as f:
f.write(value)
print 'Saved to File Successfully'