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

Предполагая, что у вас есть байтовая строка, например

"\ x12 \ x45 \ x00 \ xAB"

, и вы знаете количество байтов и их тип, вы также можете использовать это подход

import struct

bytes = '\x12\x45\x00\xAB'
val = struct.unpack('

Поскольку я указывал немного endian (используя символ '& lt;') в начале строки формата, функция возвращала десятичный эквивалент.

0x12 = 18

0x45 = 69

0xAB00 = 43776

B равно одному байту (8 бит) без знака

H равно двум байтам (16 бит) unsigned

Более доступные символы и размеры байтов можно найти здесь

Преимущества:

Вы можете укажите более одного байта и endian значений

Недостатки ..

Вам действительно нужно знать тип и длину данных, которые вы имеете дело с

811
задан Erwin Brandstetter 9 April 2017 в 19:00
поделиться

3 ответа

Хотите, чтобы получившийся файл был на сервере или на клиенте?

На стороне сервера

Если вам нужно что-то простое для повторного использования или автоматизации, вы можете использовать Postgresql's встроенная команда COPY . например,

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

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

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

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

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

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


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

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

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

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

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

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

From документация :

Не путайте КОПИРОВАНИЕ с инструкцией psql \ copy. \ copy вызывает COPY FROM STDIN или COPY TO STDOUT, а затем извлекает / сохраняет данные в файле, доступном для клиента psql. Таким образом, доступность файла и права доступа зависят от клиента, а не от сервера, когда используется \ copy.

Ваш язык программирования приложений может также поддерживать отправку или выборку данных, но обычно вы не можете использовать ] КОПИРОВАТЬ ИЗ СТАНДАРТА / В СТАНДАРТ в стандартном операторе SQL, потому что нет способа подключить поток ввода / вывода. Обработчик PHP PostgreSQL ( не PDO) включает очень простые функции pg_copy_from и pg_copy_to , которые копируют в / из массива PHP, что может быть неэффективно для больших наборов данных. .

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

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

1279
ответ дан 22 November 2019 в 21:11
поделиться

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

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

См. man psql для получения помощи по используемым здесь параметрам.

17
ответ дан 22 November 2019 в 21:11
поделиться

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

11
ответ дан 22 November 2019 в 21:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: