it-swarm.it

Il comando Postgres client copy (\ copy) non ha accesso a una tabella temporanea?

Sto generando un elenco di comandi SQL per esportare alcuni dati che alla fine eseguo usando psql -f. Le query ottengono tutte lo stesso sottoinsieme di dati, quindi ho pensato di fattorizzare le qualifiche e inserire un elenco di ID utente idonei in tabelle temporanee come queste

create temporary table tmp_export_users as (select id from users where ...)

quindi fare riferimento a quello nei miei comandi\copy come

\copy (select ... from table where user_id in (select id from tmp_export_users)) TO 'filename.csv' WITH CSV HEADER

Questi sono tutti nello stesso file, uno per riga, e li eseguono -f Ottengo l'errore che i comandi di copia non riescono a vedere la tabella temporanea, quindi suppongo che il comando di copia del client non debba effettivamente utilizzare gli stessi postgres sessione come psql.

È corretto? C'è un modo per cambiare quel comportamento?

8
jkebinger

\copy può utilizzare una tabella temporanea.

Prima ho provato e confermato questo con la versione 9.0 dalla riga di comando.
Quindi ho creato un file con SQL e psql meta command \copy utilizzando più tabelle temporanee. Questo ha funzionato anche per me.

CREATE TEMP TABLE tmp as SELECT * FROM tbl;
\copy (SELECT * FROM tmp JOIN tbl USING (id)) TO '/var/lib/postgres/test1.csv';

Chiamata:

psql -p5432 mydb -f test.sql

Nota il punto e virgola finale, che è facoltativo alla fine di un file (terminato implicitamente), ma richiesto dopo qualsiasi altra istruzione SQL e anche dopo l'ultimo se eseguito in psql in modo interattivo.

Normalmente , i meta-comandi psql non possono essere mescolati con SQL sulla stessa riga in un file eseguito per psql -f. Cito il manuale su psql :

L'analisi degli argomenti si interrompe alla fine della riga o quando viene trovata un'altra barra rovesciata non quotata. Una barra rovesciata non quotata viene considerata come l'inizio di un nuovo meta-comando. La sequenza speciale \\ (due barre rovesciate) segna la fine degli argomenti e continua ad analizzare i comandi SQL, se presenti. In questo modo i comandi SQL e psql possono essere liberamente miscelati su una riga. Ma in ogni caso, gli argomenti di un meta-comando non possono continuare oltre la fine della riga.

Si applicano regole diverse dopo\copy, anche se. In sostanza, psql torna automaticamente alla modalità SQL dopo \copy Vedi:

Ma hai scritto di avere tutti i comandi su righe separate. Quindi questa non può essere la spiegazione nel tuo caso.


A parte questo, hai considerato di usare COPY (il comando SQL ) invece di \copy (il psql meta-command )?

Naturalmente, il file di destinazione dovrebbe essere locale al server in questo caso non il client. E si applicano privilegi di file diversi. Il manuale :

I file denominati in un comando COPY vengono letti o scritti direttamente dal server, non dall'applicazione client. Pertanto, devono risiedere o essere accessibili al computer server database, non al client. Devono essere accessibili e leggibili o scrivibili dall'utente PostgreSQL (l'ID utente utilizzato dal server), non dal client.

16