Jawaban:
Apakah Anda ingin file yang dihasilkan di server, atau di klien?
Jika Anda menginginkan sesuatu yang mudah digunakan kembali atau diotomatisasi, Anda dapat menggunakan perintah COPY bawaan Postgresql . misalnya
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
Pendekatan ini berjalan sepenuhnya pada server jauh - tidak dapat menulis ke PC lokal Anda. Itu juga perlu dijalankan sebagai "pengguna super" Postgres (biasanya disebut "root") karena Postgres tidak dapat menghentikannya melakukan hal-hal buruk dengan sistem file lokal mesin itu.
Itu tidak benar-benar berarti Anda harus terhubung sebagai superuser (mengotomatisasi yang akan menjadi risiko keamanan dari jenis yang berbeda), karena Anda dapat menggunakan yang SECURITY DEFINER
pilihan untukCREATE FUNCTION
membuat fungsi yang berjalan seolah-olah Anda superuser .
Bagian penting adalah bahwa fungsi Anda ada untuk melakukan pemeriksaan tambahan, tidak hanya memotong keamanan - sehingga Anda dapat menulis fungsi yang mengekspor data persis yang Anda butuhkan, atau Anda dapat menulis sesuatu yang dapat menerima berbagai pilihan selama mereka temui daftar putih yang ketat. Anda perlu memeriksa dua hal:
GRANT
s dalam database, tetapi fungsinya sekarang berjalan sebagai superuser, sehingga tabel yang biasanya "di luar batas" akan dapat diakses sepenuhnya. Anda mungkin tidak ingin membiarkan seseorang memanggil fungsi Anda dan menambahkan baris di akhir tabel "pengguna" Anda ...Saya telah menulis posting blog yang diperluas dengan pendekatan ini , termasuk beberapa contoh fungsi yang mengekspor (atau mengimpor) file dan tabel yang memenuhi persyaratan ketat.
Pendekatan lain adalah melakukan penanganan file di sisi klien , yaitu di aplikasi atau skrip Anda. Server Postgres tidak perlu tahu file apa yang Anda salin, hanya memuntahkan data dan klien meletakkannya di suatu tempat.
Sintaks dasar untuk ini adalah COPY TO STDOUT
perintah, dan alat grafis seperti pgAdmin akan membungkusnya untuk Anda dalam dialog yang bagus.
The psql
baris perintah klien memiliki khusus "meta-command" yang disebut \copy
, yang mengambil semua pilihan sama dengan "nyata" COPY
, tetapi dijalankan dalam klien:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
Perhatikan bahwa tidak ada terminasi ;
, karena meta-command diakhiri oleh baris baru, tidak seperti perintah SQL.
Dari dokumen :
Jangan bingung COPY dengan instruksi psql \ copy. \ copy meminta COPY DARI STDIN atau COPY TO STDOUT, dan kemudian mengambil / menyimpan data dalam file yang dapat diakses oleh klien psql. Dengan demikian, aksesibilitas file dan hak akses bergantung pada klien daripada server ketika \ copy digunakan.
Bahasa pemrograman aplikasi Anda juga mungkin memiliki dukungan untuk mendorong atau mengambil data, tetapi Anda umumnya tidak dapat menggunakan COPY FROM STDIN
/ TO STDOUT
dalam pernyataan SQL standar, karena tidak ada cara untuk menghubungkan aliran input / output. PostgreSQL handler PHP ( bukan PDO) mencakup fungsi yang sangat mendasar pg_copy_from
dan pg_copy_to
yang disalin ke / dari array PHP, yang mungkin tidak efisien untuk set data besar.
\copy
berfungsi juga - di sana, jalur relatif ke klien, dan tidak ada titik koma yang diperlukan / diizinkan. Lihat hasil edit saya.
\copy
perlu menjadi satu-liner. Jadi Anda tidak mendapatkan keindahan memformat sql seperti yang Anda inginkan, dan hanya menempatkan salinan / fungsi di sekitarnya.
\copy
adalah meta-perintah khusus di psql
klien baris perintah . Itu tidak akan berfungsi pada klien lain, seperti pgAdmin; mereka mungkin akan memiliki alat sendiri, seperti penyihir grafis, untuk melakukan pekerjaan ini.
Ada beberapa solusi:
psql
perintahpsql -d dbname -t -A -F"," -c "select * from users" > output.csv
Ini memiliki keuntungan besar yang bisa Anda gunakan melalui SSH, seperti ssh postgres@host command
- memungkinkan Anda untuk mendapatkannya
copy
perintah 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
Semuanya bisa digunakan dalam skrip, tapi saya lebih suka # 1.
Di terminal (saat terhubung ke db) atur output ke file cvs
1) Setel pemisah bidang ke ','
:
\f ','
2) Setel format output tidak selaras:
\a
3) Hanya tampilkan tupel:
\t
4) Tetapkan output:
\o '/tmp/yourOutputFile.csv'
5) Jalankan permintaan Anda:
:select * from YOUR_TABLE
6) Output:
\o
Anda kemudian dapat menemukan file csv Anda di lokasi ini:
cd /tmp
Salin menggunakan scp
perintah atau edit menggunakan nano:
nano /tmp/yourOutputFile.csv
COPY
atau \copy
pendekatan menangani dengan benar (convert ke format CSV standar); Melakukan hal ini?
Jika Anda tertarik pada semua kolom tabel tertentu bersama dengan header, Anda bisa menggunakannya
COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
Ini sedikit lebih sederhana daripada
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
yang, setahu saya, setara.
Informasi ini tidak terwakili dengan baik. Karena ini adalah kedua kalinya saya perlu menurunkan ini, saya akan meletakkan ini di sini untuk mengingatkan diri saya jika tidak ada yang lain.
Sungguh cara terbaik untuk melakukan ini (mengeluarkan CSV dari postgres) adalah dengan menggunakan COPY ... TO STDOUT
perintah. Meskipun Anda tidak ingin melakukannya dengan cara yang ditunjukkan dalam jawaban di sini. Cara yang benar untuk menggunakan perintah adalah:
COPY (select id, name from groups) TO STDOUT WITH CSV HEADER
Ini bagus untuk digunakan lebih dari ssh:
$ ssh psqlserver.example.com 'psql -d mydb "COPY (select id, name from groups) TO STDOUT WITH CSV HEADER"' > groups.csv
Ini bagus untuk digunakan di dalam docker di atas ssh:
$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
Ini bahkan hebat di mesin lokal:
$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
Atau di dalam buruh pelabuhan di mesin lokal ?:
docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
Atau di cluster kubernetes, di buruh pelabuhan, melalui HTTPS ??:
kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
Sangat fleksibel, banyak koma!
Ya saya lakukan, ini catatan saya:
Menggunakan /copy
operasi file yang dijalankan secara efektif pada sistem apa pun yang psql
dijalankan perintah, sebagai pengguna yang menjalankannya 1 . Jika Anda terhubung ke server jarak jauh, mudah untuk menyalin file data pada sistem yang menjalankan psql
ke / dari server jarak jauh.
COPY
mengeksekusi operasi file di server sebagai akun pengguna proses backend (default postgres
), jalur file dan izin diperiksa dan diterapkan sesuai. Jika menggunakan TO STDOUT
maka pemeriksaan file izin dilewati.
Kedua opsi ini memerlukan perpindahan file selanjutnya jika psql
tidak dijalankan pada sistem di mana Anda ingin CSV yang dihasilkan berada. Ini adalah kasus yang paling mungkin, menurut pengalaman saya, ketika Anda kebanyakan bekerja dengan server jarak jauh.
Lebih kompleks untuk mengkonfigurasi sesuatu seperti terowongan TCP / IP lewat ssh ke sistem jarak jauh untuk output CSV sederhana, tetapi untuk format output lainnya (biner) mungkin lebih baik untuk /copy
melewati koneksi tunneled, mengeksekusi lokal psql
. Dalam nada yang sama, untuk impor besar, memindahkan file sumber ke server dan menggunakan COPY
mungkin merupakan opsi dengan kinerja tertinggi.
Dengan parameter psql Anda dapat memformat output seperti CSV tetapi ada kelemahannya karena harus ingat untuk menonaktifkan pager dan tidak mendapatkan header:
$ 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,,
Tidak, saya hanya ingin mengeluarkan CSV dari server saya tanpa mengkompilasi dan / atau menginstal alat.
psql
dapat melakukan ini untuk Anda:
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:~$
Lihat man psql
bantuan tentang opsi yang digunakan di sini.
Versi baru - psql 12 - akan mendukung --csv
.
--csv
Beralih ke mode keluaran CSV (Comma-Separated Values). Ini sama dengan \ pset format csv .
csv_fieldsep
Menentukan pemisah bidang yang akan digunakan dalam format output CSV. Jika karakter pemisah muncul dalam nilai bidang, bidang itu adalah output dalam tanda kutip ganda, mengikuti aturan standar CSV. Standarnya adalah koma.
Pemakaian:
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
Di pgAdmin III ada opsi untuk mengekspor ke file dari jendela kueri. Di menu utama itu Permintaan -> Jalankan ke file atau ada tombol yang melakukan hal yang sama (itu adalah segitiga hijau dengan floppy disk biru sebagai lawan dari segitiga hijau polos yang hanya menjalankan permintaan). Jika Anda tidak menjalankan kueri dari jendela kueri, maka saya akan melakukan apa yang disarankan IMSoP dan menggunakan perintah salin.
Saya telah menulis alat kecil yang disebut psql2csv
merangkum COPY query TO STDOUT
pola, menghasilkan CSV yang tepat. Antarmukanya mirip dengan psql
.
psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY
Permintaan diasumsikan sebagai isi STDIN, jika ada, atau argumen terakhir. Semua argumen lain diteruskan ke psql kecuali untuk ini:
-h, --help show help, then exit
--encoding=ENCODING use a different encoding than UTF8 (Excel likes LATIN1)
--no-header do not output a header
Jika Anda memiliki kueri yang lebih panjang dan Anda ingin menggunakan psql kemudian masukkan kueri Anda ke file dan gunakan perintah berikut:
psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv
-F","
daripada -F";"
menghasilkan file CSV yang akan terbuka dengan benar di MS Excel
Saya sangat merekomendasikan DataGrip , IDE basis data oleh JetBrains. Anda dapat mengekspor kueri SQL ke file CSV , dan dapat mengatur tunneling ssh dengan mudah. Ketika dokumentasi merujuk ke "set hasil", itu berarti hasil dikembalikan oleh kueri SQL di konsol.
Saya tidak terkait dengan DataGrip, saya suka produk ini!
JackDB , klien basis data di peramban web Anda, menjadikan ini sangat mudah. Apalagi jika Anda menggunakan Heroku.
Ini memungkinkan Anda terhubung ke basis data jauh dan menjalankan query SQL pada mereka.
Sumber
(sumber: jackdb.com )
Setelah DB terhubung, Anda dapat menjalankan kueri dan mengekspor ke CSV atau TXT (lihat kanan bawah).
Catatan: Saya sama sekali tidak berafiliasi dengan JackDB. Saat ini saya menggunakan layanan gratis mereka dan berpikir itu adalah produk hebat.
Sesuai permintaan @ skeller88, saya mengepos ulang komentar saya sebagai jawaban agar tidak hilang oleh orang-orang yang tidak membaca setiap tanggapan ...
Masalah dengan DataGrip adalah bahwa ia mencengkeram dompet Anda. Ini tidak gratis. Coba edisi komunitas DBeaver di dbeaver.io. Ini adalah alat database multi-platform FOSS untuk pemrogram SQL, DBA, dan analis yang mendukung semua basis data populer: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto, dll.
DBeaver Community Edition membuatnya sepele untuk terhubung ke database, mengeluarkan pertanyaan untuk mengambil data, dan kemudian mengunduh hasil yang ditetapkan untuk menyimpannya ke CSV, JSON, SQL, atau format data umum lainnya. Ini adalah pesaing FOSS yang layak untuk TOAD untuk Postgres, TOAD untuk SQL Server, atau Toad untuk Oracle.
Saya tidak memiliki afiliasi dengan DBeaver. Saya suka harga dan fungsionalitasnya, tetapi saya berharap mereka akan membuka aplikasi DBeaver / Eclipse lebih banyak dan membuatnya mudah untuk menambahkan widget analytics ke DBeaver / Eclipse, daripada meminta pengguna untuk membayar langganan tahunan untuk membuat grafik dan grafik langsung di dalam aplikasi. Keahlian coding Java saya berkarat dan saya merasa tidak butuh waktu berminggu-minggu untuk mempelajari kembali cara membuat widget Eclipse, hanya untuk menemukan bahwa DBeaver telah menonaktifkan kemampuan untuk menambahkan widget pihak ketiga ke Edisi Komunitas DBeaver.
Apakah pengguna DBeaver memiliki wawasan tentang langkah-langkah untuk membuat widget analytics untuk ditambahkan ke Edisi Komunitas DBeaver?
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'