Příkaz Postgres client copy (\ copy) nemá ' přístup k dočasné tabulce?

Generuji seznam příkazů SQL pro export některých dat, která nakonec spustím pomocí psql -f. Všechny dotazy dostávají stejnou podmnožinu dat, tak jsem si myslel, že „vyřadím kvalifikaci a vložím seznam způsobilých uživatelských ID do dočasných tabulek, jako je

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

a potom se k tomu vrátím v mém \ copy příkazy jako

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

Všechny jsou ve stejném souboru, jeden na řádek a jejich spuštění – pokud dostanu chybu, kterou mohou kopírovat příkazy “ Nevidím dočasnou tabulku, takže hádám, že příkaz kopírování klienta nesmí ve skutečnosti používat stejnou relaci postgres jako psql.

Je to správné? Existuje způsob, jak toto chování změnit?

Odpověď

\copy může použít dočasnou tabulku.

Nejprve jsem to otestoval a potvrdil s verzí 9.0 na příkazovém řádku.
Pak jsem vytvořil soubor s meta příkazem SQL a psql \copy pomocí více dočasných tabulek. To fungovalo i pro mě.

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

Volejte:

psql -p5432 mydb -f test.sql 

Všimněte si ukončení středník, který je volitelný na konci souboru (ukončen implicitně), ale je vyžadován po jakémkoli jiném příkazu SQL a také po posledním, pokud je spuštěn v psql interaktivně.

Normálně nelze meta příkazy psql kombinovat s SQL na stejném řádku v souboru spuštěném za psql -f. Cituji příručku pro psql :

Analýza argumentů se zastaví na konci řádku, nebo když je nalezeno jiné zpětné lomítko bez uvozovek. Nekotované zpětné lomítko je považováno za začátek nového meta-příkazu. Speciální sekvence \\ (dvě zpětná lomítka) označuje konec argumentů a pokračuje v analýze příkazů SQL, pokud existují. Tímto způsobem lze na řádku libovolně kombinovat příkazy SQL a psql. V každém případě však argumenty meta-příkazu nemohou pokračovat až za konec řádku.

after \copy. V zásadě se psql automaticky přepne zpět do režimu SQL po \copy Viz:

Ale napsal jsi, že jsi měl všechny příkazy na samostatných řádcích. To tedy ve vašem případě nemůže být vysvětlení.


Kromě toho jste zvážili použití COPY ( příkaz SQL ) namísto \copy ( psql meta-příkaz )?

Cílový soubor by samozřejmě musel být local to the server v tomto případě není klient. A platí různá oprávnění k souborům. Příručka :

Soubory pojmenované v COPY Příkaz čte nebo zapisuje přímo server, nikoli klientská aplikace. Proto musí být umístěny na počítači databázového serveru nebo musí být k němu přístupné, nikoli klientovi. Musí být přístupné a čitelné nebo zapisovatelné uživatelem PostgreSQL (ID uživatele, pod kterým server běží), nikoli klientem.

Komentáře

  • kopie běží jako uživatel postgresu, \ copy zabalí kopii, aby zapisovala na standardní hodnotu a byla přesměrována na soubor, do kterého ji odešlete. Můžete také zavolat psql, použít \ o k odeslání výstupu do souboru a poté spustit kopii na stdout, abyste získali podobný efekt.
  • Abyste si byli jisti, spustil jsem test v mé odpovědi se superuživatelem (postgres ) a fiktivní uživatel. Oba pracují pro mě. Stejné výsledky ve verzi 8.4.
  • Ano, to, zda má uživatel postgres unix přístup k věcem jako / tmp, závisí na věcech, jako je to, zda je SELinux nainstalován či nikoliv a jestli ho pustí z krabice. \ Copy nebo copy to stdout jsou určitě dva spolehlivější způsoby, jak kopii používat.
  • Děkuji za odpovědi všem. Vypadá to, že jsem opomněl ukončit řádek, který vytvořil dočasnou tabulku středníkem, takže se to ' nevytvořilo. Nyní funguje podle očekávání

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *