PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Salva l'output PL/pgSQL da PostgreSQL in un file CSV

Vuoi il file risultante sul server o sul client?

Lato server

Se vuoi qualcosa di facile da riutilizzare o automatizzare, puoi usare il comando COPY integrato di Postgresql. es.

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

Questo approccio viene eseguito interamente sul server remoto - non può scrivere sul tuo PC locale. Deve anche essere eseguito come un "superutente" Postgres (normalmente chiamato "root") perché Postgres non può impedirgli di fare cose brutte con il filesystem locale di quella macchina.

Ciò in realtà non significa che devi essere connesso come superutente (automatizzare ciò sarebbe un rischio per la sicurezza di diverso tipo), perché puoi usare il SECURITY DEFINER opzione per CREATE FUNCTION per creare una funzione che funziona come se fossi un superutente .

La parte cruciale è che la tua funzione è lì per eseguire controlli aggiuntivi, non solo bypassare la sicurezza, quindi potresti scrivere una funzione che esporti i dati esatti di cui hai bisogno, oppure potresti scrivere qualcosa che può accettare varie opzioni purché soddisfare una rigorosa whitelist. Devi controllare due cose:

  1. Quali file l'utente dovrebbe essere autorizzato a leggere/scrivere su disco? Potrebbe trattarsi di una directory particolare, ad esempio, e il nome del file potrebbe dover avere un prefisso o un'estensione adatti.
  2. Quali tabelle l'utente dovrebbe essere in grado di leggere/scrivere nel database? Questo sarebbe normalmente definito da GRANT s nel database, ma la funzione ora è in esecuzione come superutente, quindi le tabelle che normalmente sarebbero "fuori limite" saranno completamente accessibili. Probabilmente non vuoi permettere a qualcuno di invocare la tua funzione e aggiungere righe alla fine della tua tabella "utenti"...

Ho scritto un post sul blog in cui si espande questo approccio, inclusi alcuni esempi di funzioni che esportano (o importano) file e tabelle che soddisfano condizioni rigorose.

Lato cliente

L'altro approccio consiste nel gestire i file sul lato client , ovvero nell'applicazione o nello script. Il server Postgres non ha bisogno di sapere su quale file stai copiando, sputa semplicemente i dati e il client li mette da qualche parte.

La sintassi sottostante è COPY TO STDOUT comando e strumenti grafici come pgAdmin lo avvolgeranno in una bella finestra di dialogo.

Il psql client a riga di comando ha uno speciale "meta-comando" chiamato \copy , che accetta tutte le stesse opzioni del COPY "reale". , ma viene eseguito all'interno del client:

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

Nota che non ci sono ; di terminazione , perché i meta-comandi vengono terminati da newline, a differenza dei comandi SQL.

Dai documenti:

Non confondere COPIA con l'istruzione psql \copy. \copy richiama COPY FROM STDIN o COPY TO STDOUT, quindi recupera/memorizza i dati in un file accessibile al client psql. Pertanto, l'accessibilità ai file ei diritti di accesso dipendono dal client piuttosto che dal server quando viene utilizzato \copy.

Il tuo linguaggio di programmazione dell'applicazione può hanno anche il supporto per il push o il recupero dei dati, ma in genere non puoi utilizzare COPY FROM STDIN /TO STDOUT all'interno di un'istruzione SQL standard, perché non c'è modo di collegare il flusso di input/output. Il gestore PostgreSQL di PHP (non PDO) include pg_copy_from molto semplice e pg_copy_to funzioni che copiano in/da un array PHP, che potrebbero non essere efficienti per set di dati di grandi dimensioni.