Kommandoen Postgres client copy (\ copy) har ' ikke tilgang til en midlertidig tabell?

Jeg genererer en liste over SQL-kommandoer for å eksportere noen data som jeg til slutt kjører ved hjelp av psql -f. Spørringene får samme delsett med data, så jeg trodde jeg hadde trukket ut kvalifikasjonene og satt en liste over kvalifiserte bruker-ID-er i midlertidige tabeller som det.

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

og henvis tilbake 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 per linje, og kjører dem -f jeg får feilen som kopikommandoer kan » ikke se den midlertidige tabellen, så jeg antar at klientkopieringskommandoen faktisk ikke må bruke samme postgres-økt som psql.

Er det riktig? Er det en måte å endre atferden på?

Svar

\copy kan bruke en midlertidig tabell.

Først testet jeg og bekreftet dette med versjon 9.0 på kommandolinjen.
Så opprettet jeg en fil med SQL og psql metakommando \copy flere midlertidige tabeller. Det fungerte også for meg.

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 

Legg merke til avslutningen semikolon, som er valgfritt på slutten av en fil (avsluttes implisitt), men kreves etter enhver annen SQL-setning og også etter den siste hvis den utføres i psql interaktivt.

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

Analysering av argumenter stopper på slutten av linjen, eller når en annen ubemerket tilbakeslag er funnet. Et unotert tilbakeslag er tatt som begynnelsen på en ny metakommando. Den spesielle sekvensen \\ (to tilbakeslag) markerer slutten på argumenter og fortsetter å analysere SQL-kommandoer, hvis noen. På den måten kan SQL- og psql-kommandoer blandes fritt på en linje. Men uansett kan ikke argumentene til en metakommando fortsette utover slutten av linjen.

Forskjellige regler gjelder etter \copy. I hovedsak bytter psql tilbake til SQL-modus automatisk etter \copy Se:

Men du skrev at du hadde alle kommandoene på separate linjer. Så det kan ikke være forklaringen i ditt tilfelle.


Alt til side, har du vurdert å bruke COPY ( SQL-kommandoen ) i stedet for \copy ( psql metakommandoen )?

Selvfølgelig må målfilen være lokal til serveren ikke klienten i dette tilfellet. Og forskjellige filrettigheter gjelder. Håndboken :

Filer navngitt i COPY -kommandoen leses eller skrives direkte av serveren, ikke av klientapplikasjonen. Derfor må de være på eller være tilgjengelig for databaseservermaskinen, ikke for klienten. De må være tilgjengelige for og lesbare eller skrivbare av PostgreSQL-brukeren (bruker-ID-en serveren kjører som), ikke klienten.

Kommentarer

  • kopi kjører som postgres-bruker, \ copy wraps copy for å skrive for å std ut og omdirigeres til filen du sender den til. Du kan også ringe psql, bruke \ o for å sende utdata til en fil, og deretter kjøre en kopi til stdout for å få lignende effekt.
  • For å være sikker på at jeg kjørte testen i svaret mitt med en superbruker (postgres ) og en dummy-bruker. Begge fungerer for meg. Samme resultater på v8.4.
  • Ja, hvorvidt postgres unix-brukeren kan få tilgang til ting som / tmp, avhenger av ting som om SELinux er installert eller ikke, og om det lar det komme ut av esken. Kopien eller kopien til stdout er definitivt de to mer pålitelige måtene å bruke kopi på.
  • Takk for svarene alle sammen. Det ser ut til at jeg forsømte å avslutte linjen som opprettet en midlertidig tabell med semikolon, så det ble ikke '. Jobber som forventet nå

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *