Az SQL parancsok listáját generálom néhány adat exportálásához, amelyeket végül a psql -f használatával futtatok. A lekérdezések mindegyike ugyanazt az adathalmazt kapja, úgy gondoltam, hogy ki fogom vonni a képesítéseket, és egy ideiglenes táblázatokba felrakom a jogosult felhasználói azonosítók listáját, például a következőt:
create temporary table tmp_export_users as (select id from users where ...)
majd erre utalok vissza a \ copy parancsok, például
\copy (select ... from table where user_id in (select id from tmp_export_users)) TO "filename.csv" WITH CSV HEADER
Ezek mind ugyanazon fájlban vannak, soronként egy, és futtatják őket -f kapom azt a hibát, amelyet a másolási parancsok képesek ” Nem látom az ideiglenes táblázatot, ezért arra tippelek, hogy az ügyfélmásolási parancs valójában nem használhatja ugyanazt a postgres munkamenetet, mint a psql.
Ez helyes? Van-e mód a viselkedés megváltoztatására?
Válasz
\copy
ideiglenes táblázatot használhat.
Először ezt teszteltem és megerősítettem a 9.0 a parancssorban.
Ezután létrehoztam egy fájlt SQL és psql meta paranccsal \copy
a több ideiglenes táblázat. Ez nekem is bevált.
CREATE TEMP TABLE tmp as SELECT * FROM tbl; \copy (SELECT * FROM tmp JOIN tbl USING (id)) TO "/var/lib/postgres/test1.csv";
Hívás:
psql -p5432 mydb -f test.sql
Vegye figyelembe a végződést pontosvessző, amely opcionális egy fájl végén (implicit módon megszűnik), de szükséges bármely más SQL utasítás után, és az utolsó után is, ha interaktívan hajtják végre psql-ben.
Általában , a psql meta-parancsok nem keverhetők az SQL azonos soron egy fájlban, amelyet psql -f
szerint hajtanak végre. Idézem a psql kézikönyvét:
Az argumentumok elemzése leáll a a vonal, vagy ha egy másik nem idézett visszavonás található. A nem idézett visszavonás egy új meta-parancs kezdetének számít. Az
\\
speciális szekvencia (két visszavágás) jelöli az argumentumok végét, és folytatja az SQL parancsok elemzését, ha vannak ilyenek. Így az SQL és a psql parancsok szabadon keverhetők egy vonalon. De a meta-parancs argumentumai mindenesetre nem folytathatók a sor végén.
Különböző szabályok érvényesek em után > \copy
. Lényegében a psql automatikusan visszakapcsol SQL módba \copy
után. Lásd:
De azt írta, hogy minden parancs külön soron volt. Tehát ez nem lehet a magyarázat a te esetedben.
Mindezt félretéve, fontolóra vetted a COPY
(a SQL parancs ) a \copy
( a psql meta-parancs )?
Természetesen a célfájlnak local a kiszolgálóhoz ebben az esetben nem az ügyfél. Különböző fájljogosultságok érvényesek. A kézikönyv :
A
COPY
parancsot közvetlenül a szerver olvassa vagy írja, nem pedig az ügyfélalkalmazás. Ezért az adatbázis-kiszolgáló gépen kell tartózkodniuk, vagy hozzáférhetőnek kell lenniük, nem az ügyfél számára. Ezeknek a PostgreSQL felhasználónak kell hozzáférhetőnek lennie, és olvashatónak vagy írhatónak kell lennie (az a felhasználói azonosító, amellyel a szerver fut), nem az ügyfélnek.
Megjegyzések
- a copy a postgres felhasználóként fut, a \ copy copy csomagolja a másolatot, hogy az SD-be írjon, és átirányítsák azt a fájlt, amelyre elküldi. Hívhatja a psql-t is, a \ o segítségével kimenetet küldhet egy fájlba, majd futtathat egy példányt az stdout-ra, hogy hasonló hatást érjen el.
- Annak biztosítása érdekében, hogy a válaszomban futtattam a tesztet egy superuser-rel (postgres ) és egy próbabábu felhasználó. Mindkettő nekem dolgozik. Ugyanezek az eredmények a v8.4-en.
- Igen, attól függ, hogy a postgres unix felhasználó hozzáfér-e a / tmp-hez hasonló dolgokhoz, attól függ, hogy a SELinux telepítve van-e, és ha kibocsátja a dobozából. A \ copy vagy copy az stdout-ra mindenképpen a két megbízhatóbb módszer a copy használatára.
- Köszönöm a válaszokat mindenkinek. Úgy tűnik, hogy elhagytam az ideiglenes táblázatot létrehozó sort pontosvesszővel végezni, ezért nem jött létre '. A várakozásoknak megfelelően működik most