Zapisz wyjście PL / pgSQL z PostgreSQL do pliku CSV

Jaki jest najprostszy sposób na zapisanie wyjścia PL/pgSQL z bazy danych PostgreSQL do pliku CSV?

Używam PostgreSQL 8.4 z pgAdmin III i wtyczką PSQL, z której uruchamiam zapytania.

Author: Erwin Brandstetter, 2009-10-05

14 answers

Czy chcesz plik wynikowy na serwerze, czy na kliencie?

Strona serwera

Jeśli chcesz czegoś łatwego do ponownego użycia lub zautomatyzowania, możesz użyć wbudowanego w Postgresql polecenia COPY. np.

Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',';

To podejście działa w całości na zdalnym serwerze - nie może pisać na lokalnym komputerze. Musi być również uruchomiony jako Postgres "superuser" (zwykle nazywany "root"), ponieważ Postgres nie może powstrzymać go od robienia paskudnych rzeczy z lokalnym komputerem system plików.

To nie znaczy, że musisz być podłączony jako superużytkownik( automatyzacja byłaby zagrożeniem bezpieczeństwa innego rodzaju), ponieważ możesz użyć opcji SECURITY DEFINER, Aby CREATE FUNCTION aby utworzyć funkcję, która działa tak, jakbyś był superużytkownikiem .

Kluczową częścią jest to, że twoja funkcja jest tam, aby wykonać dodatkowe kontrole, a nie tylko omijać zabezpieczenia - abyś mógł napisać funkcję, która eksportuje dokładne dane, których potrzebujesz, lub możesz napisz coś, co może akceptować różne opcje, o ile spełniają ścisłą białą listę. Musisz sprawdzić dwie rzeczy:

  1. jakie pliki powinien mieć możliwość odczytu/zapisu na dysku? Na przykład może to być konkretny katalog, a nazwa pliku musi mieć odpowiedni prefiks lub rozszerzenie.
  2. jakie tabele powinny być w stanie odczytywać/zapisywać w bazie danych? Zwykle jest to zdefiniowane przez GRANTs w bazie danych, ale funkcja działa teraz jako superużytkownik, więc tabele, które normalnie byłyby "poza granicami", będą w pełni dostępne. Prawdopodobnie nie chcesz pozwolić, aby ktoś wywołał twoją funkcję i dodał wiersze na końcu tabeli "użytkownicy" ... ]}

Napisałem post na blogu rozwijający to podejście, zawierający przykłady funkcji, które eksportują (lub importują) pliki i tabele spełniające ścisłe warunki.


Strona klienta

Inne podejście to zrobić obsługa plików po stronie klienta, czyli w Twojej aplikacji lub skrypcie. Serwer Postgres nie musi wiedzieć, do jakiego pliku kopiujesz, po prostu wypluwa Dane i klient gdzieś je umieszcza.

Podstawową składnią tego polecenia jest COPY TO STDOUT, A narzędzia graficzne, takie jak pgAdmin, zawiążą je w ładnym oknie dialogowym.

The psql klient linii poleceń posiada specjalne "meta-polecenie" o nazwie \copy, który przyjmuje wszystkie te same opcje co "prawdziwe" COPY, ale jest uruchamiane wewnątrz klienta:

\copy (Select * From foo) To '/tmp/test.csv' With CSV

Zauważ, że nie ma zakończenia ;, ponieważ meta-polecenia są zakończone znakiem nowej linii, w przeciwieństwie do poleceń SQL.

From the docs :

Nie należy mylić COPY z instrukcją psql \ copy. \copy wywołuje polecenie COPY ze STDIN lub COPY na STDOUT, a następnie pobiera/przechowuje dane w pliku dostępnym dla klienta psql. Tak więc dostępność plików i prawa dostępu zależą od klienta, a nie od serwer gdy używany jest \copy.

Twój język programowania aplikacji Może mieć również wsparcie dla przesuwania lub pobierania danych, ale zazwyczaj nie możesz używać COPY FROM STDIN/TO STDOUT w standardowym poleceniu SQL, ponieważ nie ma możliwości podłączenia strumienia wejścia/wyjścia. PHP ' s PostgreSQL handler (not PDO) zawiera bardzo podstawowe pg_copy_from oraz pg_copy_to funkcje kopiujące do / Z Tablicy PHP, co może nie być efektywne dla dużych zbiorów danych.

 1068
Author: IMSoP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-14 12:49:26

Istnieje kilka rozwiązań:

1 psql polecenie

psql -d dbname -t -A -F"," -c "select * from users" > output.csv

Ma to dużą zaletę, że można go używać przez SSH, jak ssh postgres@host command - umożliwiając uzyskanie

2 Postgres copy command

COPY (SELECT * from users) To '/tmp/output.csv' With CSV;

3 PSQL interactive (or not)

>psql dbname
psql>\f ','
psql>\a
psql>\o '/tmp/output.csv'
psql>SELECT * from users;
psql>\q

Wszystkie mogą być używane w skryptach, ale wolę #1.

4 pgadmin ale to nie jest skrypt.

 419
Author: sorin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-19 04:39:52

W terminalu (po podłączeniu do db) Ustaw wyjście do pliku cvs

1) Ustaw separator pola na ',':

\f ','

2) Ustaw format wyjściowy bez oznaczenia:

\a

3) Pokaż tylko krotki:

\t

4) Ustaw wyjście:

\o '/tmp/yourOutputFile.csv'

5) Wykonaj zapytanie:

:select * from YOUR_TABLE

6) wyjście:

\o

Następnie będziesz mógł znaleźć swój plik csv w tej lokalizacji:

cd /tmp

Skopiuj go za pomocą polecenia scp lub edytuj za pomocą nano:

nano /tmp/yourOutputFile.csv
 79
Author: Marcin Wasiluk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-16 12:49:50

Jeśli interesują Cię wszystkie kolumny konkretnej tabeli wraz z nagłówkami, możesz użyć

COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;

To jest trochę prostsze niż

COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
Które, według mojej najlepszej wiedzy, są równoważne.
 32
Author: benjwadams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-11 20:34:59

Musiałem użyć \COPY, ponieważ otrzymałem komunikat o błędzie:

ERROR:  could not open file "/filepath/places.csv" for writing: Permission denied

Więc użyłem:

\Copy (Select address, zip  From manjadata) To '/filepath/places.csv' With CSV;

I działa

 20
Author: maudulus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-26 13:19:12

psql może to zrobić dla Ciebie:

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:~$

Zobacz man psql aby uzyskać pomoc na temat używanych tutaj opcji.

 16
Author: Dirk Eddelbuettel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-04 23:12:13

W pgAdmin III istnieje opcja eksportu do pliku z okna zapytania. W menu głównym jest zapytanie - > wykonaj do pliku lub jest przycisk, który robi to samo (jest to zielony trójkąt z niebieską dyskietką, w przeciwieństwie do zwykłego zielonego trójkąta, który po prostu uruchamia zapytanie). Jeśli nie uruchamiasz zapytania z okna zapytania, to zrobię to, co zasugerował IMSoP i użyję polecenia Kopiuj.

 11
Author: Amanda Nyren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-04 16:58:59

Pracuję nad AWS Redshift, który nie obsługuje funkcji COPY TO.

Moje narzędzie BI obsługuje CSV rozdzielane tabulatorami, więc użyłem następującego:

 psql -h  dblocation  -p port -U user  -d dbname  -F $'\t' --no-align -c " SELECT *   FROM TABLE" > outfile.csv
 9
Author: calcsam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-14 23:15:34

Ta informacja nie jest zbyt dobrze reprezentowana. Ponieważ jest to drugi raz, kiedy muszę to wyprowadzić, umieszczę to tutaj, aby przypomnieć sobie, jeśli nic innego.

Naprawdę najlepszym sposobem na to (usunięcie CSV z postgres) jest użycie komendy COPY ... TO STDOUT. Chociaż nie chcesz tego zrobić w sposób pokazany w odpowiedziach tutaj. Poprawnym sposobem użycia polecenia jest:

COPY (select id, name from groups) TO STDOUT WITH CSV HEADER

Zapamiętaj tylko jedno polecenie!

Jest świetny do użycia przez ssh:

$ ssh psqlserver.example.com 'psql -d mydb "COPY (select id, name from groups) TO STDOUT WITH CSV HEADER"' > groups.csv

To świetne do użycia wewnątrz Dockera przez ssh:

$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
To jest nawet świetne na lokalnej maszynie:
$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
Czy wewnątrz Dockera na lokalnej maszynie?:
docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
Czy na klastrze kubernetes, w dockerze, przez HTTPS??:
kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv

Tak wszechstronny, dużo przecinków!

Czy ty w ogóle?

Tak zrobiłem, oto moje notatki:

The COPYses

Użycie /copy skutecznie wykonuje operacje na plikach na dowolnym systemie, na którym jest uruchomione polecenie psql, jako użytkownik kto go wykonuje1. Jeśli łączysz się ze zdalnym serwerem, łatwo jest skopiować pliki danych z systemu wykonującego psql do / z serwera zdalnego.

COPY wykonuje operacje na plikach na serwerze jako konto użytkownika procesu zaplecza (domyślnie postgres), ścieżki plików i uprawnienia są sprawdzane i odpowiednio stosowane. Jeśli używasz TO STDOUT, sprawdzanie uprawnień plików jest pomijane.

Obie te opcje wymagają późniejszego przemieszczania pliku, jeśli {[9] } nie jest wykonywana na system, w którym docelowo ma znajdować się wynikowy plik CSV. Jest to najbardziej prawdopodobny przypadek, z mojego doświadczenia, kiedy głównie pracujesz z serwerami zdalnymi.

Bardziej skomplikowane jest skonfigurowanie czegoś takiego jak tunel TCP/IP przez ssh do zdalnego systemu dla prostego wyjścia CSV, ale dla innych formatów wyjściowych (binarnych) może być lepiej /copy przez połączenie tunelowane, wykonując lokalny psql. W podobny sposób, w przypadku dużych importów, przeniesienie pliku źródłowego na serwer i użycie COPY jest prawdopodobnie opcja o najwyższej wydajności.

Parametry PSQL

Z parametrami psql możesz sformatować wyjście jak CSV, ale są minusy, takie jak konieczność pamiętania o wyłączeniu pagera i nie otrzymywaniu nagłówków:

$ 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,,

Inne Narzędzia

Nie, chcę tylko usunąć CSV z mojego serwera bez kompilowania i / lub instalowania narzędzia.

 9
Author: joshperry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-24 01:17:06

Napisałem małe narzędzie o nazwie psql2csv to enkapsuje wzór COPY query TO STDOUT, w wyniku czego powstaje właściwy CSV. Jego interfejs jest podobny do psql.

psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY

Zakłada się, że kwerenda jest zawartością STDIN, jeśli jest obecna, lub ostatnim argumentem. Wszystkie inne argumenty są przekazywane do psql z wyjątkiem tych:

-h, --help           show help, then exit
--encoding=ENCODING  use a different encoding than UTF8 (Excel likes LATIN1)
--no-header          do not output a header
 6
Author: fphilipe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-18 16:42:31

Jeśli masz dłuższe zapytanie i lubisz używać psql, umieść zapytanie w pliku i użyj następującego polecenia:

psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv
 5
Author: Andres Kull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-18 19:52:49

Próbowałem kilku rzeczy, ale mniej z nich było w stanie dać mi żądany plik csv ze szczegółami nagłówka.

OTO, CO DLA MNIE ZADZIAŁAŁO.

Psql-d dbame-U username-c "Kopiuj (wybierz * z tabeli) na STDOUT z nagłówkiem CSV" > OUTPUT_CSV_FILE.csv

 2
Author: pyAddict,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 08:14:23

JackDB , klient bazy danych w przeglądarce internetowej, ułatwia to. Zwłaszcza jeśli jesteś na Heroku.

Pozwala łączyć się ze zdalnymi bazami danych i uruchamiać na nich zapytania SQL.

Źródłojackdb-heroku http://static.jackdb.com/assets/img/blog/jackdb-heroku-oauth-connect.gif


Po podłączeniu DB możesz uruchomić zapytanie i wyeksportować je do pliku CSV lub TXT(patrz u dołu po prawej).


jackdb-export

Uwaga: nie jestem w żaden sposób powiązany z JackDB. Obecnie korzystam z ich bezpłatnych usług i uważam, że jest to świetny produkt.

 1
Author: Dennis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:25
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'
 -3
Author: user9279273,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-27 10:56:14