it-swarm.asia

احفظ خرج PL/pgSQL من PostgreSQL إلى ملف CSV

ما هي أسهل طريقة لحفظ إخراج PL/pgSQL من قاعدة بيانات PostgreSQL إلى ملف CSV؟

أنا أستخدم PostgreSQL 8.4 مع pgAdmin III و PSQL المساعد حيث أقوم بتشغيل الاستعلامات من.

783
Hoff

هل تريد الملف الناتج على الخادم ، أو على العميل؟

جانب الخادم

إذا كنت تريد إعادة استخدام شيء ما أو تشغيله تلقائيًا ، فيمكنك استخدام أمر Postgresql المدمج في COPY . مثلا.

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

تعمل هذه الطريقة تمامًا على الخادم البعيد - لا يمكنها الكتابة إلى جهاز الكمبيوتر المحلي الخاص بك. يجب أيضًا تشغيله كـ "مستخدم خارق" لـ Postgres (يطلق عليه عادة "root") لأن Postgres لا يمكنه إيقافه عن فعل أشياء سيئة مع نظام الملفات المحلي لهذا الجهاز.

هذا لا يعني في الواقع أنك يجب أن تكون متصلاً كمستخدم خارق (التشغيل التلقائي سيكون مخاطرة أمنية من نوع مختلف) ، لأنه يمكنك استخدام خيار SECURITY DEFINER إلى CREATE FUNCTION لإنشاء وظيفة والتي تعمل ك على الرغم من أنك كنت الخارق.

الجزء الأساسي هو أن وظيفتك موجودة لإجراء فحوصات إضافية ، وليس مجرد تأمين جانبي - حتى تتمكن من كتابة وظيفة تقوم بتصدير البيانات الدقيقة التي تحتاجها ، أو يمكنك كتابة شيء يمكنه قبول خيارات مختلفة طالما كانت تلبية قائمة بيضاء صارمة. تحتاج إلى التحقق من شيئين:

  1. أي الملفات يجب أن يسمح للمستخدم القراءة/الكتابة على القرص؟ قد يكون هذا دليلًا محددًا ، على سبيل المثال ، وقد يتعين أن يكون لاسم الملف بادئة أو ملحق مناسب.
  2. أي الجداول يجب أن يكون المستخدم قادراً على القراءة/الكتابة في قاعدة البيانات؟ يمكن تعريف ذلك عادةً بـ GRANTs في قاعدة البيانات ، لكن الوظيفة تعمل الآن كمستخدم خارق ، لذلك ستكون الجداول التي ستكون عادةً "خارج الحدود" متاحة بالكامل. ربما لا تريد السماح لشخص ما باستدعاء وظيفتك وإضافة صفوف في نهاية جدول "المستخدمون" ...

لقد كتبت منشور مدونة يتوسع في هذا النهج ، بما في ذلك بعض أمثلة الوظائف التي تقوم بتصدير (أو استيراد) الملفات والجداول التي تفي بشروط صارمة.


جانب العميل

الطريقة الأخرى هي القيام بمعالجة الملف من جانب العميل ، أي في التطبيق أو البرنامج النصي. لا يحتاج خادم Postgres إلى معرفة الملف الذي تنسخ إليه ، بل يبصق البيانات ويضعها العميل في مكان ما.

بناء الجملة الأساسي لهذا هو الأمر COPY TO STDOUT ، وستقوم الأدوات الرسومية مثل pgAdmin بلفها لك في مربع حوار Nice.

عميل سطر الأوامرpsqlله "meta-command" خاص يسمى\copy، والذي يأخذ نفس الخيارات مثل "الحقيقي" COPY ، ولكن يتم تشغيله داخل العميل:

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

لاحظ أنه لا يوجد ; إنهاء ، لأن أوامر التعريف يتم إنهاؤها بخط جديد ، على عكس أوامر SQL.

من المستندات :

لا تخلط بين نسخ مع تعليمات\نسخة psql.\copy تستدعي COPY FROM STDIN أو COPY TO STDOUT ، ثم تقوم بإحضار/تخزين البيانات في ملف يمكن للعميل psql الوصول إليه. وبالتالي ، تعتمد إمكانية الوصول إلى الملفات وحقوق الوصول على العميل بدلاً من الخادم عند استخدام\copy.

لغة برمجة التطبيق الخاصة بك قدأيضًا لديها دعم لدفع البيانات أو جلبها ، لكن لا يمكنك استخدام COPY FROM STDINTO STDOUT عمومًا ضمن عبارة SQL قياسية ، لأنه لا توجد طريقة لتوصيل دفق الإدخال/الإخراج. معالج POSTGRESQL الخاص بـ PHP ( NOTPDO) يتضمن دالتين _/pg_copy_from و pg_copy_to أساسيتين للغاية والتي تنسخ إلى/من مجموعة PHP ، والتي قد لا تكون فعالة لمجموعات البيانات الكبيرة.

1187
IMSoP

هناك العديد من الحلول:

1 psql command

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

هذا له ميزة كبيرة يمكنك استخدامها عبر SSH ، مثل ssh [email protected] command - مما يتيح لك الحصول عليها

2 postgres copy command

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

3 psql التفاعلية (أو لا)

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

يمكن استخدامها جميعًا في البرامج النصية ، لكنني أفضل # 1.

4 pgadmin ولكن هذا ليس النصي.

453
sorin

في المحطة الطرفية (أثناء الاتصال بـ db) ، قم بتعيين الإخراج على ملف cvs

1) اضبط حقل seperator على ',':

\f ','

2) تعيين تنسيق الإخراج غير محاذاة:

\a

3) عرض tuples فقط:

\t

4) ضبط الانتاج:

\o '/tmp/yourOutputFile.csv'

5) تنفيذ الاستعلام الخاص بك:

:select * from YOUR_TABLE

6) الإخراج:

\o

ستتمكن بعد ذلك من العثور على ملف csv في هذا الموقع:

cd /tmp

انسخها باستخدام الأمر scp أو قم بالتحرير باستخدام nano:

nano /tmp/yourOutputFile.csv
84
Marcin Wasiluk

إذا كنت مهتمًا بـ الكل أعمدة جدول معين مع رؤوس ، فيمكنك استخدامها

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

هذا هو أبسط قليلا من

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

والتي ، على حد علمي ، متكافئة.

34
benjwadams

اضطررت إلى استخدام\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;

وانها تعمل

22
maudulus

توحيد تصدير CSV

هذه المعلومات ليست ممثلة تمثيلا جيدا حقا. نظرًا لأن هذه هي المرة الثانية التي أحتاج فيها إلى اشتقاق هذا ، فسأضع هذا هنا لتذكير نفسي إن لم يكن هناك شيء آخر.

أفضل طريقة للقيام بذلك (الحصول على CSV من postgres) هي استخدام الأمر 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

أو على كتلة kubernetes ، في عامل ميناء ، عبر 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

باستخدام معلمات 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 من الخادم دون تجميع و/أو تثبيت أداة.

20
joshperry

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 للحصول على مساعدة بشأن الخيارات المستخدمة هنا.

16
Dirk Eddelbuettel

أنا أعمل على 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
11
calcsam

في pgAdmin III ، يوجد خيار للتصدير إلى ملف من نافذة الاستعلام. في القائمة الرئيسية ، يكون Query -> Execute to file أو يوجد زر يقوم بنفس الشيء (إنه مثلث أخضر به قرص مرن أزرق بدلاً من المثلث الأخضر العادي الذي يقوم بتشغيل الاستعلام فقط). إذا كنت لا تقوم بتشغيل الاستعلام من نافذة الاستعلام ، فسأفعل ما اقترحه IMSoP واستخدم الأمر copy.

11
Amanda Nyren

الإصدار الجديد - psql 12 - سيدعم --csv.

psql - devel

--csv

التبديل إلى وضع الإخراج CSV (قيم مفصولة بفواصل). هذا يعادل\pset format 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
7
Lukasz Szozda

لقد كتبت أداة صغيرة تسمى 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
6
fphilipe

جربت العديد من الأشياء ، لكن القليل منهم تمكنوا من إعطائي ملف CSV المطلوب مع تفاصيل العنوان.

هنا هو ما عملت بالنسبة لي.

psql -d dbame -U username \
  -c "COPY ( SELECT * FROM TABLE ) TO STDOUT WITH CSV HEADER " > \
  OUTPUT_CSV_FILE.csv
5
pyAddict

إذا كان لديك استعلام أطول وترغب في استخدام psql ، فضع الاستعلام في ملف واستخدم الأمر التالي:

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

لتنزيل ملف CSV بأسماء الأعمدة كـ HEADER ، استخدم هذا الأمر:

Copy (Select * From tableName) To '/tmp/fileName.csv' With CSV HEADER;
2
murli

JackDB ، عميل قاعدة البيانات في متصفح الويب الخاص بك ، يجعل هذا الأمر سهلاً حقًا. خاصة إذا كنت على Heroku.

يتيح لك الاتصال بقواعد البيانات البعيدة وتشغيل استعلامات SQL عليها.

المصدر jackdb-heroku http://static.jackdb.com/assets/img/blog/jackdb-heroku-oauth-connect.gif


بمجرد اتصال قاعدة البيانات الخاصة بك ، يمكنك تشغيل استعلام وتصديره إلى CSV أو TXT (انظر أسفل اليمين).


jackdb-export

ملاحظة: أنا في أي حال من الأحوال تابعة JackDB. أستخدم حاليًا خدماتهم المجانية وأعتقد أنه منتج رائع.

1
Dennis