Apakah Anda ingin file yang dihasilkan di server, atau di klien?
Sisi server
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 di 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 berarti Anda harus terhubung sebagai pengguna super (mengotomatiskan itu akan menjadi risiko keamanan yang berbeda), karena Anda dapat menggunakan SECURITY DEFINER
pilihan untuk CREATE FUNCTION
untuk membuat fungsi yang berjalan seolah-olah Anda adalah pengguna super .
Bagian penting adalah bahwa fungsi Anda ada untuk melakukan pemeriksaan tambahan, bukan hanya melewati keamanan - sehingga Anda dapat menulis fungsi yang mengekspor data persis yang Anda butuhkan, atau Anda dapat menulis sesuatu yang dapat menerima berbagai opsi selama mereka memenuhi daftar putih yang ketat. Anda perlu memeriksa dua hal:
- Berkas yang mana haruskah pengguna diizinkan membaca/menulis di disk? Ini mungkin direktori tertentu, misalnya, dan nama file mungkin harus memiliki awalan atau ekstensi yang sesuai.
- Yang tabel haruskah pengguna dapat membaca/menulis dalam database? Ini biasanya ditentukan oleh
GRANT
s di database, tetapi fungsinya sekarang berjalan sebagai pengguna super, jadi tabel yang biasanya "di luar batas" akan dapat diakses sepenuhnya. Anda mungkin tidak ingin seseorang memanggil fungsi Anda dan menambahkan baris di akhir tabel "pengguna" Anda...
Saya telah menulis posting blog yang memperluas pendekatan ini, termasuk beberapa contoh fungsi yang mengekspor (atau mengimpor) file dan tabel yang memenuhi persyaratan ketat.
Sisi klien
Pendekatan lainnya adalah melakukan penanganan file di sisi klien , yaitu di aplikasi atau skrip Anda. Server Postgres tidak perlu mengetahui file apa yang Anda salin, itu hanya mengeluarkan data dan klien meletakkannya di suatu tempat.
Sintaks yang mendasari untuk ini adalah COPY TO STDOUT
perintah, dan alat grafis seperti pgAdmin akan membungkusnya untuk Anda dalam dialog yang bagus.
psql
klien baris perintah memiliki "meta-command" khusus yang disebut \copy
, yang mengambil semua opsi yang sama dengan COPY
"asli" , tetapi dijalankan di dalam klien:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
Perhatikan bahwa tidak ada penghentian ;
, karena perintah-meta diakhiri oleh baris baru, tidak seperti perintah SQL.
Dari dokumen:
Jangan bingung COPY dengan instruksi psql \copy. \copy memanggil COPY FROM 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 saat \copy digunakan.
Bahasa pemrograman aplikasi Anda mungkin juga memiliki dukungan untuk mendorong atau mengambil data, tetapi Anda biasanya tidak dapat menggunakan COPY FROM STDIN
/TO STDOUT
dalam pernyataan SQL standar, karena tidak ada cara untuk menghubungkan aliran input/output. Pengendali PostgreSQL PHP (tidak PDO) mencakup pg_copy_from
yang sangat mendasar dan pg_copy_to
fungsi yang menyalin ke/dari larik PHP, yang mungkin tidak efisien untuk kumpulan data besar.