Сохранить вывод PL/pgSQL из PostgreSQL в CSV-файл

каков самый простой способ сохранить вывод PL/pgSQL из базы данных PostgreSQL в CSV-файл?

Я использую PostgreSQL 8.4 с плагином pgAdmin III и PSQL, из которого я запускаю запросы.

14 ответов


вам нужен результирующий файл на сервере или на клиенте?

сервер

если вы хотите что-то простое для повторного использования или автоматизации, вы можете использовать встроенный Postgresql скопировать. например,

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

этот подход работает полностью на удаленном сервере - он не может писать на локальный ПК. Он также должен запускаться как "суперпользователь" Postgres (обычно называемый "root"), потому что Postgres не может остановить его вещи с локальной файловой системой этой машины.

это на самом деле не означает, что вы должны быть подключены как суперпользователь (автоматизация, которая была бы угрозой безопасности другого рода), потому что вы можете использовать the до CREATE FUNCTION сделать функцию, которая работает, как будто вы суперпользователь.

решающая часть заключается в том, что ваша функция предназначена для выполнения дополнительных проверок, а не только для обхода безопасности, чтобы вы могли написать функция, которая экспортирует точные данные, которые вам нужны, или вы можете написать что-то, что может принимать различные варианты, если они соответствуют строгому белому списку. Вам нужно проверить две вещи:

  1. , который файлы должен ли пользователь иметь возможность читать / писать на диске? Это может быть определенный каталог, например, и имя файла может иметь подходящий префикс или расширение.
  2. , который таблицы должен ли пользователь иметь возможность читать / писать в базе данных? Обычно это определяется как GRANTs в базе данных, но функция теперь работает как суперпользователь, поэтому таблицы, которые обычно были бы" вне пределов", будут полностью доступны. Вероятно, вы не хотите, чтобы кто-то вызывал вашу функцию и добавлял строки в конец вашей таблицы "пользователи"...

я написал запись в блоге развивая этот подход, включая некоторые примеры функций, экспортирующих (или импортирующих) файлы и таблицы жесткое условие.


стороне клиента

другой подход -выполните обработку файлов на стороне клиента, т. е. в вашем приложении или скрипте. Серверу Postgres не нужно знать, в какой файл вы копируете, он просто выплевывает данные, и клиент помещает их куда-то.

базовый синтаксис для этого есть COPY TO STDOUT command и графические инструменты, такие как pgAdmin, обернут его для вас в хороший диалог.

на имеет специальную "мета-команду" под названием \copy, который принимает все те же параметры, что и "реальный" COPY, но запускается внутри клиента:

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

обратите внимание, что нет прекращения ;, потому что мета-команды завершаются новой строкой, в отличие от команд SQL.

С документы:

не путайте COPY с psql инструкция \копировать. \copy вызывает COPY из STDIN или COPY в STDOUT, а затем извлекает / сохраняет данные в файле, доступном клиенту psql. Таким образом, доступность файлов и права доступа зависят от клиента, а не от сервера при использовании \copy.

ваш язык программирования приложений мая также есть поддержка для нажатия или извлечения данных, но вы обычно не можете использовать COPY FROM STDIN/TO STDOUT в стандартной инструкции SQL, потому что нет никакого способа подключение потока ввода / вывода. Обработчик PostgreSQL PHP (не PDO) включает в себя очень простой pg_copy_from и pg_copy_to функции, которые копируют в / из массива PHP, что может быть неэффективно для больших наборов данных.


есть несколько решений:

1 psql команда

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

это имеет большое преимущество, что вы можете использовать его через SSH, как ssh [email protected] command - позволит вам получить

2 postgres copy команда

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

3 psql interactive (или нет)

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

все они могут использоваться в скриптах, но я предпочитаю #1.

4 pgadmin, но это не по сценарию.


в терминале (при подключении к БД) установите вывод в файл cvs

1) Установите разделитель полей в ',':

\f ','

2) установить формат вывода unaligned:

\a

3) показывать только кортежи:

\t

4) установить на выходе:

\o '/tmp/yourOutputFile.csv'

5) выполните запрос:

:select * from YOUR_TABLE

6) выходная мощность:

\o

затем вы сможете найти свой csv-файл в этом местонахождение:

cd /tmp

скопируйте его с помощью scp команда или редактирование с помощью nano:

nano /tmp/yourOutputFile.csv

Если вы заинтересованы в все столбцы конкретной таблицы вместе с заголовками, вы можете использовать

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

Это немного проще, чем

COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;

которые, насколько мне известно, эквивалентны.


мне пришлось использовать \COPY, потому что я получил сообщение об ошибке:

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

поэтому я использовал:

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

и работает


psql можем сделать это для вас:

[email protected]:~$ 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
[email protected]:~$

посмотреть man psql для справки по параметрам, используемым здесь.


в pgAdmin III есть возможность экспортировать в файл из окна запроса. В главном меню это Query - > Execute to file или есть кнопка, которая делает то же самое (это зеленый треугольник с синей дискетой, в отличие от простого зеленого треугольника, который просто запускает запрос). Если вы не запускаете запрос из окна запроса, я бы сделал то, что предложил IMSoP, и использовал команду copy.


Я работаю над AWS Redshift, который не поддерживает COPY TO характеристика.

мой инструмент BI поддерживает CSV с разделителями табуляции, поэтому я использовал следующее:

 psql -h  dblocation  -p port -U user  -d dbname  -F $'\t' --no-align -c " SELECT *   FROM TABLE" > outfile.csv

эта информация не очень хорошо представлены. Поскольку это уже второй раз, когда мне нужно получить это, я помещу это здесь, чтобы напомнить себе, если ничего другого.

действительно лучший способ сделать это (получить CSV из postgres) - использовать . Хотя вы не хотите делать это так, как показано в ответах здесь. Правильный способ использования команды:

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

помню только одну команду!

это отлично подходит для использования по ssh:

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

это отлично подходит для использования внутри docker по ssh:

$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv

это даже здорово на локальном компьютере:

$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv

или внутри докера на локальной машине?:

docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv

или на кластере kubernetes, в docker, через HTTPS??:

kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv

настолько универсальный, много запятых!

ты вообще?

Да, я сделал, вот мои заметки:

В COPYses

используя /copy эффективно выполняет файловые операции в любой системе psql команда выполняется, как пользователь, который ее выполняет1. При подключении к удаленному серверу достаточно просто скопировать файлы данных в систему, выполняющую psql в / с удаленного сервера.

COPY выполняет файловые операции на сервере в качестве учетной записи пользователя бэкэнд-процесса (по умолчанию postgres), пути к файлам и разрешения проверяются и применяются соответственно. При использовании файл проверки разрешений обходятся.

оба эти параметра требуют последующего перемещения файла, если psql не выполняется в системе, где вы хотите, чтобы результирующий CSV в конечном итоге находился. Это наиболее вероятный случай, по моему опыту, когда вы в основном работаете с удаленными серверами.

сложнее настроить что-то вроде туннеля TCP/IP через ssh для удаленной системы для простого вывода CSV, но для других выходных форматов (двоичных) может быть лучше /copy по туннельному соединению выполняется локальное psql. В аналогичном ключе для большого импорта переместите исходный файл на сервер и используйте COPY, вероятно, самый высокопроизводительный вариант.

параметры PSQL

с параметрами psql вы можете форматировать вывод, как CSV, но есть и недостатки, такие как необходимость помнить, чтобы отключить пейджер и не получать заголовки:

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

Другие Инструменты

Нет, я просто хочу получить CSV из моего сервер без компиляции и/или установки инструмента.


я написал небольшой инструмент под названием psql2csv, который инкапсулирует COPY query TO STDOUT шаблон, в результате чего правильный CSV. Это интерфейс похож на psql.

psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY

предполагается, что запрос является содержимым STDIN, если он присутствует, или последним аргументом. Все остальные аргументы передаются в psql, за исключением следующих:

-h, --help           show help, then exit
--encoding=ENCODING  use a different encoding than UTF8 (Excel likes LATIN1)
--no-header          do not output a header

Если у вас больше запросов и вы хотите использовать psql, поместите запрос в файл и используйте следующую команду:

psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv

Я попробовал несколько вещей, но меньше из них смог дать мне желаемый csv с подробностями заголовка.

ВОТ ЧТО СРАБОТАЛО ДЛЯ МЕНЯ.

psql-d dbame-U username-c "копировать ( выбрать * из таблицы ) в STDOUT с заголовком CSV" > OUTPUT_CSV_FILE.csv


JackDB, клиент базы данных в вашем веб-браузере, делает это очень легко. Особенно если ты на Heroku.

Он позволяет подключаться к удаленным базам данных и запускать SQL-запросы на них.

источникjackdb-heroku http://static.jackdb.com/assets/img/blog/jackdb-heroku-oauth-connect.gif


Как только ваша БД подключена, вы можете запустить запрос и экспортировать в CSV или TXT (см. внизу справа).


jackdb-export

Примечание: я никоим образом не связан с JackDB. В настоящее время я использую их бесплатные услуги и думаю, что это отличный продукт.


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'