Искате ли получения файл на сървъра или на клиента?
Сървърна страна
Ако искате нещо лесно за повторно използване или автоматизиране, можете да използвате вградената команда COPY на Postgresql. напр.
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
Този подход работи изцяло на отдалечения сървър - не може да пише на вашия локален компютър. Освен това трябва да се стартира като „суперпотребител“ на Postgres (обикновено наричан „root“), защото Postgres не може да го спре да прави гадни неща с локалната файлова система на тази машина.
Това всъщност не означава, че трябва да сте свързани като суперпотребител (автоматизирането би било риск за сигурността от различен вид), защото можете да използвате SECURITY DEFINER
опция за CREATE FUNCTION
за да създадете функция, която работи сякаш сте суперпотребител .
Решаващата част е, че вашата функция е там, за да извършва допълнителни проверки, а не просто да заобикаля защитата - така че можете да напишете функция, която експортира точните данни, от които се нуждаете, или можете да напишете нещо, което може да приема различни опции, стига да отговарят на строг бял списък. Трябва да проверите две неща:
- Кои файлове трябва ли на потребителя да бъде разрешено да чете/записва на диск? Това може да е конкретна директория, например, и името на файла може да трябва да има подходящ префикс или разширение.
- Кои таблици трябва ли потребителят да може да чете/записва в базата данни? Това обикновено се дефинира от
GRANT
s в базата данни, но функцията вече работи като суперпотребител, така че таблиците, които обикновено биха били "извън границите", ще бъдат напълно достъпни. Вероятно не искате да позволите на някой да извика вашата функция и да добави редове в края на вашата таблица „потребители“...
Написах публикация в блог, разширяваща този подход, включително някои примери за функции, които експортират (или импортират) файлове и таблици, отговарящи на строги условия.
Клиентска страна
Другият подход е да извършите обработката на файлове от страна на клиента , т.е. във вашето приложение или скрипт. Сървърът на Postgres не трябва да знае към кой файл копирате, той просто изхвърля данните и клиентът ги поставя някъде.
Основният синтаксис за това е COPY TO STDOUT
команда, а графичните инструменти като pgAdmin ще го обвият вместо вас в приятен диалогов прозорец.
psql
клиент от команден ред има специална "мета-команда", наречена \copy
, който приема всички същите опции като "истинското" COPY
, но се изпълнява вътре в клиента:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
Имайте предвид, че няма завършващ ;
, тъй като метакомандите се прекратяват с нов ред, за разлика от SQL командите.
От документите:
Не бъркайте COPY с инструкцията на psql \copy. \copy извиква COPY ОТ STDIN или COPY TO STDOUT и след това извлича/съхранява данните във файл, достъпен за psql клиента. По този начин достъпността на файловете и правата за достъп зависят от клиента, а не от сървъра, когато се използва \copy.
Вашият език за програмиране на приложения може също имат поддръжка за бутане или извличане на данните, но обикновено не можете да използвате COPY FROM STDIN
/TO STDOUT
в рамките на стандартен SQL оператор, тъй като няма начин за свързване на входно/изходния поток. Обработчикът PostgreSQL на PHP (не PDO) включва много основния pg_copy_from
и pg_copy_to
функции, които копират към/от PHP масив, което може да не е ефективно за големи набори от данни.