Відповіді:
Ви хочете отриманий файл на сервері чи на клієнті?
Якщо ви хочете щось легко використати або автоматизувати, ви можете використовувати вбудовану команду 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 OF STDIN або COPY TO STDOUT, а потім отримує / зберігає дані у файлі, доступному клієнту psql. Таким чином, доступність файлів та права доступу залежать від клієнта, а не від сервера, коли використовується \ copy.
Ваша мова програмування додатків може також мати підтримку для виштовхування або отримання даних, але зазвичай не можна використовувати COPY FROM STDIN
/ TO STDOUT
в стандартному операторі SQL, оскільки немає способу підключення потоку вводу / виводу. Обробник PostgreSQL PHP ( не PDO) включає в себе дуже основні pg_copy_from
та pg_copy_to
функції, які копіюють в / з масиву PHP, що може бути неефективним для великих наборів даних.
\copy
теж працює - там шляхи відносно клієнта, і крапка з комою не потрібна / дозволена. Дивіться мою редакцію.
\copy
потрібно бути однолінійним. Таким чином, ви не отримаєте красу форматування sql так, як вам потрібно, а просто помістіть навколо нього копію / функцію.
\copy
це спеціальна мета-команда в psql
клієнтському командному рядку . Він не працюватиме в інших клієнтах, таких як pgAdmin; вони, можливо, матимуть власні інструменти, такі як графічні майстри, для виконання цієї роботи.
Є кілька рішень:
psql
командаpsql -d dbname -t -A -F"," -c "select * from users" > output.csv
Це має велику перевагу в тому, що ви можете користуватися ним через SSH, наприклад, ssh postgres@host command
- це дозволяє вам отримати
copy
команда 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
Усі вони можуть бути використані в сценаріях, але я віддаю перевагу №1.
У терміналі (при підключенні до db) встановіть висновок у файл cvs
1) Встановіть сепаратор поля на ','
:
\f ','
2) Встановити вихідний формат нерівномірно:
\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
або \copy
підходять правильно (перетворюють у стандартний формат CSV); це робить?
Якщо вас цікавлять усі стовпці певної таблиці разом із заголовками, ви можете використовувати
COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
Це крихітно трохи простіше, ніж
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
які, наскільки мені відомо, рівнозначні.
Ця інформація насправді недостатньо представлена. Оскільки це вже другий раз, коли мені потрібно було це зробити, я поставлю це тут, щоб нагадати про себе, якщо нічого іншого.
Дійсно, найкращий спосіб зробити це (вивести CSV з постгресів) - використовувати COPY ... TO STDOUT
команду. Хоча ви не хочете робити це так, як показано у відповідях тут. Правильний спосіб використання команди:
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
Він відмінно підходить для використання всередині докера над 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
Або на кластері кубернетів, у докері, над HTTPS ??:
kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
Так універсально, багато коми!
Так, я зробив, ось мої замітки:
Використання /copy
ефективно виконує операції з файлами в будь-якій системі, на якій працює psql
команда, як користувач, який її виконує 1 . Якщо ви підключитесь до віддаленого сервера, просто скопіювати файли даних у систему, що виконується psql
на / з віддаленого сервера.
COPY
виконує операції з файлами на сервері, оскільки обліковий запис користувача процесу резервного копіювання (за замовчуванням postgres
), шляхи та дозволи файлів перевіряються та застосовуються відповідно. Якщо використовується, TO STDOUT
тоді перевірки дозволів на файл обходять.
Обидва ці варіанти вимагають подальшого переміщення файлів, якщо psql
він не виконується в системі, де ви хочете, щоб результат CSV в кінцевому рахунку знаходився. Це, швидше за все, з мого досвіду, коли ви в основному працюєте з віддаленими серверами.
Складніше налаштувати щось на зразок тунелю TCP / IP через ssh для віддаленої системи для простого виводу CSV, але для інших форматів виводу (бінарних) може бути краще, /copy
ніж через тунельне з'єднання, виконуючи локальне psql
. Аналогічно, для великого імпорту переміщення вихідного файлу на сервер та використання COPY
, мабуть, найбільш ефективний варіант.
За допомогою параметрів 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 зі свого сервера без компіляції та / або встановлення інструменту.
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
за допомогою до параметрів, які використовуються тут.
Нова версія - psql 12 - підтримуватиме --csv
.
--csv
Перемикається на вихідний режим CSV (значення, розділені комами). Це еквівалентно \ pset формату csv .
csv_fieldsep
Вказує роздільник поля, який буде використовуватися у вихідному форматі CSV. Якщо символ роздільника відображається у значенні поля, це поле виводиться в подвійних лапки, дотримуючись стандартних правил CSV. За замовчуванням - кома.
Використання:
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
У pgAdmin III є можливість експорту у файл із вікна запиту. У головному меню це Query -> Execute to file або є кнопка, яка робить те саме (це зелений трикутник із синьою дискетою на відміну від звичайного зеленого трикутника, який просто виконує запит). Якщо ви не запускаєте запит у вікні запиту, я б зробив те, що запропонував IMSoP, і скористався командою копіювання.
Я написав невеликий інструмент під назвою, 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
-F","
замість того, -F";"
щоб генерувати файл CSV, який би відкрився правильно у MS Excel
Я дуже рекомендую DataGrip , IDE бази даних від JetBrains. Ви можете експортувати SQL-запит у файл CSV та легко налаштувати ssh-тунелювання. Коли документація посилається на "набір результатів", вони означають результат, повернений запитом SQL в консолі.
Я не пов'язаний з DataGrip, я просто люблю продукт!
JackDB , клієнт бази даних у вашому веб-браузері, робить це дуже просто. Особливо, якщо ти на Хероку.
Він дозволяє підключатися до віддалених баз даних і запускати на них SQL запити.
Джерело
(джерело: jackdb.com )
Після підключення БД ви можете запустити запит та експортувати в CSV або TXT (див. Праворуч внизу).
Примітка. Я жодним чином не пов'язаний з JackDB. Зараз я користуюся їхніми безкоштовними послугами і думаю, що це чудовий продукт.
На запит @ skeller88 я надсилаю свій коментар як відповідь, щоб люди не втрачали кожної відповіді ...
Проблема з DataGrip полягає в тому, що він утримує ваш гаманець. Це не безкоштовно. Спробуйте спільне видання DBeaver на dbeaver.io. Це багатоплатформенний засіб баз даних FOSS для програмістів SQL, DBA та аналітиків, який підтримує всі популярні бази даних: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto тощо.
DBeaver Community Edition робить тривіальним підключення до бази даних, видавати запити для отримання даних, а потім завантажувати набір результатів, щоб зберегти їх у CSV, JSON, SQL або інших поширених форматах даних. Це життєздатний конкурент FOSS TOAD для Postgres, TOAD для SQL Server або Toad for Oracle.
Я не маю приналежності до DBeaver. Мені подобається ціна та функціональність, але я б хотів, щоб вони більше відкривали додаток DBeaver / Eclipse і полегшували додавання віджетів аналітики до DBeaver / Eclipse, а не вимагати від користувачів плати за щорічну підписку для створення графіків та діаграм безпосередньо в межах додаток. Мої навички кодування Java іржавіють, і мені не хочеться витрачати тижні, щоб вивчити, як створювати віджети Eclipse, лише щоб виявити, що DBeaver відключив можливість додавання сторонніх віджетів до DBeaver Community Edition.
Чи мають користувачі DBeaver розуміння кроків для створення віджетів аналітики для додавання до спільноти DBeaver Community?
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'