O comando copy do cliente do Postgres (\ copy) não tem acesso a uma tabela temporária?


9

Estou gerando uma lista de comandos SQL para exportar alguns dados que acabo executando usando o psql -f. Todas as consultas obtêm o mesmo subconjunto de dados, então pensei em incluir as qualificações e colocar uma lista de IDs de usuário elegíveis em tabelas temporárias como essa

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

em seguida, refira-se a isso em meus comandos \ copy, como

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

Eles estão todos no mesmo arquivo, um por linha, e os executam -f eu recebo o erro de que os comandos de cópia não podem ver a tabela temporária, portanto, acho que o comando de cópia do cliente não deve realmente usar os mesmos postgres sessão como psql.

Isso está correto? Existe uma maneira de mudar esse comportamento?

Respostas:


16

\copy pode usar uma tabela temporária.

Primeiro testei e confirmei isso com a versão 9.0 na linha de comando.
Em seguida, criei um arquivo com o comando meta SQL e psql \copyusando várias tabelas temporárias. Isso funcionou para mim também.

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

Ligar:

psql -p5432 mydb -f test.sql

Observe o ponto-e-vírgula final, que é opcional no final de um arquivo (finalizado implicitamente), mas necessário após qualquer outra instrução SQL e também após a última se executado no psql interativamente.

Normalmente , os meta-comandos psql não podem ser combinados com o SQL na mesma linha em um arquivo executado por psql -f. Cito o manual no psql :

A análise de argumentos para no final da linha ou quando outra barra invertida não citada é encontrada. Uma barra invertida não citada é tomada como o início de um novo meta-comando. A sequência especial \\(duas barras invertidas) marca o final dos argumentos e continua analisando os comandos SQL, se houver. Dessa forma, os comandos SQL e psql podem ser livremente misturados em uma linha. Mas, em qualquer caso, os argumentos de um meta-comando não podem continuar além do fim da linha.

Regras diferentes se aplicam depois \copy , no entanto. Essencialmente, o psql volta ao modo SQL automaticamente depois de \copyConsulte:

Mas você escreveu que tinha todos os comandos em linhas separadas. Portanto, essa não pode ser a explicação no seu caso.


Tudo isso à parte, você considerou usar COPY(o comando SQL ) em vez de \copy(o meta-comando psql )?

Obviamente, o arquivo de destino teria que ser local para o servidor e não o cliente nesse caso. E diferentes privilégios de arquivo se aplicam. O manual :

Os arquivos nomeados em um COPYcomando são lidos ou gravados diretamente pelo servidor, não pelo aplicativo cliente. Portanto, eles devem residir ou estar acessíveis à máquina do servidor de banco de dados, não ao cliente. Eles devem estar acessíveis e legíveis ou graváveis ​​pelo usuário do PostgreSQL (o ID do usuário no qual o servidor é executado), não pelo cliente.


copy é executado como usuário do postgres, \ copy envolve copy para gravar em std out e é redirecionado para o arquivo para o qual você o envia. Você também pode chamar o psql, usar \ o para enviar a saída para um arquivo e executar uma cópia no stdout para obter um efeito semelhante.
97811 Scott Marlowe #

Para ter certeza de que executei o teste na minha resposta com um superusuário (postgres) e um usuário fictício. Ambos trabalham para mim. Mesmos resultados na v8.4.
Erwin Brandstetter

11
Sim, se o usuário do postgres unix pode ou não acessar coisas como / tmp depende de coisas como se o SELinux está instalado ou não e se o deixa sair de sua caixa. A \ copy ou copy to stdout são definitivamente as duas maneiras mais confiáveis ​​de usar a cópia.
9788 Scott Marlowe #

11
Obrigado pelas respostas a todos. Parece que negligenciei o término da linha que criou uma tabela temporária com ponto e vírgula, para que não fosse criada. Trabalhando como esperado agora
jkebinger 9/11/11
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.