Você quer o arquivo resultante no servidor ou no cliente?
Lado do servidor
Se você quer algo fácil de reutilizar ou automatizar, você pode usar o comando COPY embutido no Postgresql. por exemplo.
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
Esta abordagem é executada inteiramente no servidor remoto - ele não pode gravar no seu PC local. Ele também precisa ser executado como um "superusuário" do Postgres (normalmente chamado de "root") porque o Postgres não pode impedi-lo de fazer coisas desagradáveis com o sistema de arquivos local dessa máquina.
Isso não significa que você precisa estar conectado como um superusuário (automatizar isso seria um risco de segurança de um tipo diferente), porque você pode usar o
SECURITY DEFINER
opção para CREATE FUNCTION
para fazer uma função que execute como se você fosse um superusuário . A parte crucial é que sua função está lá para realizar verificações adicionais, não apenas ignorar a segurança - para que você possa escrever uma função que exporte os dados exatos de que precisa ou pode escrever algo que aceite várias opções, desde que elas atender a uma lista branca estrita. Você precisa verificar duas coisas:
- Quais arquivos o usuário deve ter permissão para ler/gravar no disco? Este pode ser um diretório específico, por exemplo, e o nome do arquivo pode ter um prefixo ou extensão adequado.
- Quais tabelas o usuário deve ser capaz de ler/escrever no banco de dados? Isso normalmente seria definido por
GRANT
s no banco de dados, mas a função agora está sendo executada como um superusuário, portanto, as tabelas que normalmente estariam "fora dos limites" estarão totalmente acessíveis. Você provavelmente não quer permitir que alguém invoque sua função e adicione linhas no final da sua tabela “users”…
Escrevi uma postagem no blog expandindo essa abordagem, incluindo alguns exemplos de funções que exportam (ou importam) arquivos e tabelas que atendem a condições estritas.
Lado do cliente
A outra abordagem é fazer o manuseio de arquivos no lado do cliente , ou seja, em seu aplicativo ou script. O servidor Postgres não precisa saber para qual arquivo você está copiando, ele apenas cospe os dados e o cliente os coloca em algum lugar.
A sintaxe subjacente para isso é o
COPY TO STDOUT
comando, e ferramentas gráficas como pgAdmin irão envolvê-lo para você em uma boa caixa de diálogo. O
psql
cliente de linha de comando tem um "meta-comando" especial chamado \copy
, que usa as mesmas opções que o COPY
"real" , mas é executado dentro do cliente:\copy (Select * From foo) To '/tmp/test.csv' With CSV
Observe que não há terminação
;
, porque os metacomandos são encerrados por nova linha, ao contrário dos comandos SQL. Dos documentos:
Não confunda COPY com a instrução \copy do psql. \copy invoca COPY FROM STDIN ou COPY TO STDOUT, e então busca/armazena os dados em um arquivo acessível ao cliente psql. Assim, a acessibilidade do arquivo e os direitos de acesso dependem do cliente e não do servidor quando \copy é usado.
Sua linguagem de programação de aplicativos pode também tem suporte para enviar ou buscar os dados, mas geralmente você não pode usar
COPY FROM STDIN
/TO STDOUT
dentro de uma instrução SQL padrão, porque não há como conectar o fluxo de entrada/saída. Manipulador PostgreSQL do PHP (não PDO) inclui pg_copy_from
muito básico e pg_copy_to
funções que copiam de/para um array PHP, o que pode não ser eficiente para grandes conjuntos de dados.