Kommandoen Postgres client copy (\ copy) har ' ikke adgang til en midlertidig tabel?

Jeg genererer en liste over SQL-kommandoer til at eksportere nogle data, som jeg i sidste ende kører ved hjælp af psql -f. Forespørgslerne får alle den samme delmængde af data, så jeg troede, at jeg ville faktorere kvalifikationerne og lægge en liste over kvalificerede bruger-ider i en midlertidig tabel som sådan

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

så henvis tilbage til det i min \ kopier kommandoer som

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

Disse er alle i samme fil, en pr. linje, og kører dem -f jeg får den fejl, som kopikommandoer kan ” ikke se den midlertidige tabel, så jeg gætter på, at klientkopieringskommandoen faktisk ikke må bruge den samme postgres-session som psql.

Er det korrekt? Er der en måde at ændre denne adfærd på?

Svar

\copy kan bruge en midlertidig tabel.

Først testede jeg og bekræftede dette med version 9.0 på kommandolinjen.
Derefter oprettede jeg en fil med SQL og psql meta-kommando \copy ved hjælp af flere midlertidige tabeller. Det fungerede også for mig.

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

Ring:

psql -p5432 mydb -f test.sql 

Bemærk afslutningen semikolon, som er valgfri i slutningen af en fil (afsluttet implicit), men krævet efter enhver anden SQL-sætning og også efter den sidste, hvis den udføres i psql interaktivt.

Normalt kan , psql metakommandoer ikke blandes med SQL på samme linje i en fil udført pr. psql -f. Jeg citerer manualen på psql :

Analysering af argumenter stopper i slutningen af linjen, eller når der findes en anden ikke-citeret tilbageslag. En ikke-citeret tilbageslag tages som begyndelsen på en ny metakommando. Den specielle rækkefølge \\ (to tilbageslag) markerer slutningen af argumenter og fortsætter med at analysere SQL-kommandoer, hvis nogen. På den måde kan SQL- og psql-kommandoer blandes frit på en linje. Men under alle omstændigheder kan argumenterne for en metakommando ikke fortsætte ud over slutningen af linjen.

Forskellige regler gælder efter \copy. I det væsentlige skifter psql automatisk tilbage til SQL-tilstand efter \copy Se:

Men du skrev, at du havde alle kommandoer på separate linjer. Så det kan ikke være forklaringen i dit tilfælde.


Alt bortset fra, har du overvejet at bruge COPY ( SQL-kommandoen ) i stedet for \copy ( psql meta-kommando )?

Målfilen skal selvfølgelig være lokalt til serveren ikke klienten i dette tilfælde. Og forskellige filrettigheder gælder. Manualen :

Filer navngivet i en COPY -kommandoen læses eller skrives direkte af serveren, ikke af klientapplikationen. Derfor skal de være på eller være tilgængelige for databaseservermaskinen, ikke for klienten. De skal være tilgængelige for og læselige eller skrivbare af PostgreSQL-brugeren (bruger-idet, som serveren kører som), ikke klienten.

Kommentarer

  • kopi kører som postgres-bruger, \ copy wraps copy for at skrive for at std ud og omdirigeres til den fil, du sender den til. Du kan også ringe til psql, bruge \ o til at sende output til en fil og derefter køre en kopi til stdout for at få lignende effekt.
  • For at være sikker på, at jeg kørte testen i mit svar med en superbruger (postgres ) og en dummy-bruger. Begge fungerer for mig. Samme resultater på v8.4.
  • Ja, hvorvidt postgres unix-brugeren kan få adgang til ting som / tmp eller ej, afhænger af ting som om SELinux er installeret eller ej, og om det slipper det ud af kassen. Kopien eller kopien til stdout er bestemt de to mere pålidelige måder at bruge kopi på.
  • Tak for svarene alle sammen. Det ser ud til, at jeg forsømte at afslutte linjen, der oprettede en midlertidig tabel med et semikolon, så det blev ikke '. Arbejder som forventet nu

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *