Eu quero escrever um script para fazer backup de uma tabela usando COPY
.
psql "connection parameters" -c "COPY (SELECT * FROM tbl WHERE insertion_date > 'date') TO STDOUT WITH CSV HEADER;" | bzip2 -c > backup.csv.bz2
Agora eu quero registrar quantas linhas são copiadas para o arquivo zip? Quero calculá-lo durante a cópia, não com outro comando.
Atualização: Desde Postgres 9.3 plpgsql pode acessar o número de linhas processadas
COPY
diretamente por:Eu recentemente me deparei com o mesmo problema. Eu tentei com uma função plpgsql, mas
ROW_COUNT
não é definida porCOPY
- no Postgres 9.2 ou anterior.Você poderia apenas executar duas consultas. Primeiro
count()
e depoisCOPY
. Com consultas simples, esse é provavelmente o caminho a seguir. Mas com consultas enormes/complexas, isso é uma dor e pode dobrar o tempo de execução.Eu vim com uma solução que usa uma tabela temporária e conta as linhas antes de executar
COPY
.Eu adaptei o que tenho para você para que você possa
COPY TO STDOUT
canalizar parabzip2
, o que não é possível de dentro de uma função plpgsql:1. Crie uma função que pegue uma string SQL e crie uma tabela temporária com ela:
A função executa SQL dinâmico, portanto, você pode usá-la para qualquer consulta.
Isso é inerentemente inseguro , portanto, execute-o com os direitos mínimos necessários, revogue todos os direitos do público e conceda
EXECUTE
exclusivamente a um usuário confiável. Siga as instruções do manual !Crie uma tabela temporária com
ON COMMIT DROP
, para que ela seja descartada automaticamente no final da transação.Obter a contagem de linhas com
GET DIAGNOSTICS
-ROW_COUNT
é definido pelaSELECT
instrução emEXECUTE
. Escreva no log - sua exigência. Não há necessidade de separadocount(*)
.2. Chame do shell-script para canalizar a saída através do bzip2
Coloque dois comandos SQL em seu
-c
argumento ou coloque consultas complexas em um arquivo e use o-f
parâmetro. Tudo é executado em uma transação. Apenas a saída do último comando é retornada - atende à nossa necessidade. Cuidado com a sintaxe - múltiplas camadas de interpretação (primeiro shell, depois Postgres).O primeiro comando é a função acima com sua string de consulta como parâmetro. O segundo é o
COPY TO STDOUT
.Eu testei isso
PostgreSQL 9.1
no Linux e funcionou para mim: dados no arquivo, mensagem com contagem de linhas no log.