it-swarm.dev

Polecenie kopiowania klienta Postgres (\ copy) nie ma dostępu do tabeli tymczasowej?

Generuję listę poleceń SQL, aby wyeksportować niektóre dane, które ostatecznie uruchamiam przy użyciu psql -f. Wszystkie zapytania mają ten sam podzbiór danych, więc pomyślałem, że uwzględnię kwalifikacje i umieszczę listę kwalifikujących się identyfikatorów użytkowników w tymczasowych tabelach takich jak

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

następnie powróć do tego w moich\kopiuj poleceniach takich jak

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

Wszystkie znajdują się w tym samym pliku, po jednym w wierszu i uruchamiając je. -F Pojawia się błąd, że polecenia kopiowania nie widzą tabeli tymczasowej, więc zgaduję, że polecenie kopiowania klienta nie może faktycznie używać tego samego postgresu sesja jako psql.

Czy to jest poprawne? Czy istnieje sposób na zmianę tego zachowania?

8
jkebinger

\copy może użyć tabeli tymczasowej.

Najpierw przetestowałem i potwierdziłem to w wersji 9.0 w wierszu poleceń.
Następnie utworzyłem plik za pomocą komendy meta SQL i psql \copy przy użyciu wielu tabel tymczasowych. To też działało dla mnie.

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

Połączenie:

psql -p5432 mydb -f test.sql

Zwróć uwagę na średnik kończący, który jest opcjonalny na końcu = plik (zakończony niejawnie), ale wymagany po każdej innej instrukcji SQL, a także po ostatniej, jeśli zostanie wykonany w psql interaktywnie.

Zwykle , meta-komendy psql nie mogą być mieszane z SQL w tym samym wierszu w pliku wykonanym według psql -f. Cytuję instrukcja na psql :

Analiza argumentów kończy się na końcu wiersza lub po znalezieniu innego niecytowanego ukośnika odwrotnego. Niecytowany ukośnik jest traktowany jako początek nowej meta-komendy. Specjalna sekwencja \\ (dwa ukośniki odwrotne) oznacza koniec argumentów i kontynuuje analizowanie poleceń SQL, jeśli takie istnieją. W ten sposób polecenia SQL i psql mogą być swobodnie mieszane w linii. W każdym razie argumenty meta-polecenia nie mogą być kontynuowane poza końcem wiersza.

Obowiązują różne zasady po\copy, chociaż. Zasadniczo psql przełącza się automatycznie z powrotem do trybu SQL po \copy Widzieć:

Ale napisałeś, że masz wszystkie polecenia w osobnych wierszach. To nie może być wyjaśnienie w twoim przypadku.


Pomijając to, czy rozważałeś użycie COPY ( polecenie SQL ) zamiast \copy (the psql meta-command )?

Oczywiście plik docelowy musiałby być lokalny dla serwera , a nie klienta w tym przypadku. Obowiązują różne uprawnienia do plików. instrukcja :

Pliki o nazwach w komendzie COPY są odczytywane lub zapisywane bezpośrednio przez serwer, a nie przez aplikację kliencką. Dlatego muszą znajdować się na komputerze serwera bazy danych, a nie kliencie, lub być do niego dostępne. Muszą być one dostępne dla użytkownika PostgreSQL (możliwe do odczytania lub zapisania) (identyfikator użytkownika, na którym działa serwer), a nie klient.

16