Risposte:
Vuoi il file risultante sul server o sul client?
Se vuoi qualcosa di facile da riutilizzare o automatizzare, puoi usare il comando COPY incorporato di Postgresql . per esempio
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
Questo approccio funziona interamente sul server remoto : non può scrivere sul PC locale. Deve anche essere eseguito come un "superutente" di Postgres (normalmente chiamato "root") perché Postgres non può impedirlo di fare cose cattive con il filesystem locale di quella macchina.
Ciò non significa in realtà che devi essere connesso come un superutente (automatizzare questo sarebbe un rischio per la sicurezza di un altro tipo), perché puoi usare l' SECURITY DEFINER
opzioneCREATE FUNCTION
per creare una funzione che gira come se fossi un superutente .
La parte cruciale è che la tua funzione è lì per eseguire controlli aggiuntivi, non solo per by-pass la sicurezza - quindi potresti scrivere una funzione che esporta i dati esatti di cui hai bisogno, o potresti scrivere qualcosa che può accettare varie opzioni purché incontrare una whitelist rigorosa. Devi controllare due cose:
GRANT
s nel database, ma la funzione è ora in esecuzione come superutente, quindi le tabelle che normalmente sarebbero "fuori limite" saranno completamente accessibili. Probabilmente non vuoi permettere a qualcuno di invocare la tua funzione e aggiungere righe alla fine della tabella "utenti" ...Ho scritto un post sul blog che espande questo approccio , includendo alcuni esempi di funzioni che esportano (o importano) file e tabelle che soddisfano condizioni rigorose.
L'altro approccio consiste nell'eseguire la gestione dei file sul lato client , ovvero nell'applicazione o nello script. Il server Postgres non ha bisogno di sapere in quale file stai copiando, sputa semplicemente i dati e il client li mette da qualche parte.
La sintassi sottostante per questo è il COPY TO STDOUT
comando e strumenti grafici come pgAdmin lo avvolgeranno per te in una bella finestra di dialogo.
Il psql
client della riga di comando ha uno speciale "meta-comando" chiamato \copy
, che accetta tutte le stesse opzioni del "reale" COPY
, ma viene eseguito all'interno del client:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
Si noti che non c'è terminazione ;
, poiché i meta-comandi sono terminati da newline, a differenza dei comandi SQL.
Dai documenti :
Non confondere COPIA con l'istruzione psql \ copia. \ copy richiama COPY DA STDIN o COPY TO STDOUT, quindi recupera / archivia i dati in un file accessibile al client psql. Pertanto, l'accessibilità dei file e i diritti di accesso dipendono dal client anziché dal server quando viene utilizzato \ copy.
Il linguaggio di programmazione dell'applicazione potrebbe anche supportare la trasmissione o il recupero dei dati, ma in genere non è possibile utilizzare COPY FROM STDIN
/ TO STDOUT
all'interno di un'istruzione SQL standard, poiché non è possibile collegare il flusso di input / output. Il gestore PostgreSQL di PHP ( non PDO) include funzioni pg_copy_from
e pg_copy_to
funzioni di base che copiano da / verso un array PHP, il che potrebbe non essere efficace per grandi set di dati.
\copy
funziona anche - lì, i percorsi sono relativi al client e non è necessario / consentito il punto e virgola. Vedi la mia modifica.
\copy
debba essere un liner. Quindi non hai la bellezza di formattare sql nel modo che preferisci e di limitarti a creare una copia / funzione.
\copy
è un meta-comando speciale nel psql
client della riga di comando . Non funzionerà con altri client, come pgAdmin; probabilmente avranno i propri strumenti, come i maghi grafici, per fare questo lavoro.
Esistono diverse soluzioni:
psql
comandopsql -d dbname -t -A -F"," -c "select * from users" > output.csv
Questo ha il grande vantaggio che puoi usarlo tramite SSH, come ssh postgres@host command
- permettendoti di ottenere
copy
comando 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
Tutti possono essere usati negli script, ma preferisco il n. 1.
Nel terminale (mentre è collegato al db) imposta l'output sul file cvs
1) Impostare il separatore di campo su ','
:
\f ','
2) Impostare il formato di output non allineato:
\a
3) Mostra solo tuple:
\t
4) Imposta uscita:
\o '/tmp/yourOutputFile.csv'
5) Eseguire la query:
:select * from YOUR_TABLE
6) Uscita:
\o
Sarai quindi in grado di trovare il tuo file CSV in questa posizione:
cd /tmp
Copialo usando il scp
comando o modifica usando nano:
nano /tmp/yourOutputFile.csv
COPY
o vengono \copy
gestiti correttamente (convertiti in formato CSV standard); fa questo?
Se sei interessato a tutte le colonne di una determinata tabella con le intestazioni, puoi usare
COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
Questo è un po 'più semplice di
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
che, per quanto ne so, sono equivalenti.
Questa informazione non è davvero ben rappresentata. Dato che è la seconda volta che ho bisogno di ricavarlo, lo inserirò qui per ricordare a me stesso se non altro.
Il modo migliore per farlo (far uscire CSV da Postgres) è usare il COPY ... TO STDOUT
comando. Anche se non vuoi farlo nel modo indicato nelle risposte qui. Il modo corretto di utilizzare il comando è:
COPY (select id, name from groups) TO STDOUT WITH CSV HEADER
È ottimo per l'uso su ssh:
$ ssh psqlserver.example.com 'psql -d mydb "COPY (select id, name from groups) TO STDOUT WITH CSV HEADER"' > groups.csv
È ottimo per l'uso all'interno della finestra mobile su ssh:
$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
È persino eccezionale sulla macchina locale:
$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
O all'interno della finestra mobile sulla macchina locale ?:
docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
O su un cluster di kubernetes, nella finestra mobile, su HTTPS ??:
kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
Così versatile, molte virgole!
Sì l'ho fatto, ecco i miei appunti:
L'utilizzo /copy
esegue in modo efficace le operazioni sui file su qualsiasi sistema su cui psql
è in esecuzione il comando, come l'utente che lo esegue 1 . Se ti connetti a un server remoto, è semplice copiare i file di dati sull'esecuzione del sistemapsql
sul / dal server remoto.
COPY
esegue le operazioni sui file sul server quando l'account utente del processo back-end (impostazione predefinita postgres
), i percorsi dei file e le autorizzazioni vengono controllati e applicati di conseguenza. Se si utilizzaTO STDOUT
i controlli delle autorizzazioni dei file vengono ignorati.
Entrambe queste opzioni richiedono un successivo spostamento dei file se psql
non sono in esecuzione sul sistema in cui si desidera che il CSV risultante risieda in definitiva. Questo è il caso più probabile, nella mia esperienza, quando lavori principalmente con server remoti.
È più complesso configurare qualcosa come un tunnel TCP / IP su ssh su un sistema remoto per un semplice output CSV, ma per altri formati di output (binari) potrebbe essere meglio /copy
su una connessione tunnel, eseguendo un locale psql
. Allo stesso modo, per grandi importazioni, spostare il file di origine sul server e utilizzare COPY
è probabilmente l'opzione con le massime prestazioni.
Con i parametri psql puoi formattare l'output come CSV ma ci sono aspetti negativi come dover ricordare di disabilitare il cercapersone e non ottenere le intestazioni:
$ 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,,
No, voglio solo far uscire CSV dal mio server senza compilare e / o installare uno strumento.
psql
puoi farlo per te:
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:~$
Per man psql
assistenza sulle opzioni utilizzate qui.
La nuova versione - psql 12 - supporterà --csv
.
--csv
Passa alla modalità di uscita CSV (valori separati da virgola). Ciò equivale al formato \ pset csv .
csv_fieldsep
Specifica il separatore di campo da utilizzare nel formato di output CSV. Se il carattere di separazione appare nel valore di un campo, quel campo viene emesso tra virgolette doppie, seguendo le regole CSV standard. L'impostazione predefinita è una virgola.
Uso:
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
In pgAdmin III esiste un'opzione per esportare in file dalla finestra della query. Nel menu principale c'è Query -> Esegui su file o c'è un pulsante che fa la stessa cosa (è un triangolo verde con un floppy disk blu al contrario del triangolo verde che esegue la query). Se non esegui la query dalla finestra della query, farei ciò che suggeriva IMSoP e utilizzerei il comando copia.
Ho scritto un piccolo strumento chiamato psql2csv
che incapsula il COPY query TO STDOUT
modello, dando come risultato CSV corretto. La sua interfaccia è simile a psql
.
psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY
Si presume che la query sia il contenuto di STDIN, se presente, o l'ultimo argomento. Tutti gli altri argomenti vengono inoltrati a psql tranne questi:
-h, --help show help, then exit
--encoding=ENCODING use a different encoding than UTF8 (Excel likes LATIN1)
--no-header do not output a header
Se hai query più lunghe e ti piace usare psql, metti la tua query in un file e usa il seguente comando:
psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv
-F","
invece di -F";"
generare un file CSV che si sarebbe aperto correttamente in MS Excel
Consiglio vivamente DataGrip , un IDE di database di JetBrains. È possibile esportare una query SQL in un file CSV e configurare facilmente il tunneling ssh. Quando la documentazione fa riferimento a "set di risultati", significa che il risultato restituito da una query SQL nella console.
Non sono associato a DataGrip, adoro il prodotto!
JackDB , un client di database nel tuo browser web, lo rende davvero facile. Soprattutto se sei su Heroku.
Ti consente di connetterti a database remoti ed eseguire query SQL su di essi.
Fonte
(fonte: jackdb.com )
Una volta collegato il DB, è possibile eseguire una query ed esportare in CSV o TXT (vedere in basso a destra).
Nota: non sono in alcun modo affiliato con JackDB. Attualmente uso i loro servizi gratuiti e penso che sia un ottimo prodotto.
Su richiesta di @ skeller88, sto ripubblicando il mio commento come risposta in modo che non venga perso da persone che non leggono ogni risposta ...
Il problema con DataGrip è che fa presa sul tuo portafoglio. Non è gratuito Prova l'edizione della comunità di DBeaver su dbeaver.io. È uno strumento di database multipiattaforma FOSS per programmatori, DBA e analisti SQL che supporta tutti i database più diffusi: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto, ecc.
DBeaver Community Edition semplifica la connessione a un database, invia query per recuperare i dati, quindi scarica il set di risultati per salvarlo in CSV, JSON, SQL o altri formati di dati comuni. È un concorrente FOSS valido per TOAD per Postgres, TOAD per SQL Server o Toad per Oracle.
Non ho alcuna affiliazione con DBeaver. Adoro il prezzo e la funzionalità, ma vorrei che aprissero di più l'applicazione DBeaver / Eclipse e rendessero semplice l'aggiunta di widget di analisi a DBeaver / Eclipse, piuttosto che richiedere agli utenti di pagare l'abbonamento annuale per creare grafici e diagrammi direttamente all'interno l'applicazione. Le mie capacità di programmazione Java sono arrugginite e non ho voglia di settimane per imparare di nuovo a costruire widget di Eclipse, solo per scoprire che DBeaver ha disabilitato la possibilità di aggiungere widget di terze parti a DBeaver Community Edition.
Gli utenti di DBeaver hanno informazioni dettagliate sui passaggi per creare widget di analisi da aggiungere alla Community Edition di 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'