COPY

Nome

COPY -- copia dados entre um arquivo e uma tabela

Sinopse

COPY nome_da_tabela [ ( coluna [, ...] ) ]
    FROM { 'nome_do_arquivo' | STDIN }
    [ [ WITH ]
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimitador' ]
          [ NULL [ AS ] 'cadeia_de_caracteres_nula' ]
          [ CSV [ QUOTE [ AS ] 'demarcador' ]
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE NOT NULL coluna [, ...] ]

COPY nome_da_tabela [ ( coluna [, ...] ) ]
    TO { 'nome_do_arquivo' | STDOUT }
    [ [ WITH ]
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimitador' ]
          [ NULL [ AS ] 'cadeia_de_caracteres_nula' ]
          [ CSV [ QUOTE [ AS ] 'demarcador' ]
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE QUOTE coluna [, ...] ]

Descrição

O comando COPY copia dados entre tabelas do PostgreSQL e arquivos do sistema operacional. O comando COPY TO copia o conteúdo de uma tabela para um arquivo, enquanto o comando COPY FROM copia dados de um arquivo para uma tabela (adicionando os dados aos já existentes na tabela).

Se for especificada uma lista de colunas, o comando COPY somente copia os dados das colunas especificadas de/para o arquivo. Havendo colunas na tabela que não estejam na lista de colunas, o comando COPY FROM insere o valor padrão destas colunas.

O comando COPY com um nome de arquivo instrui o servidor PostgreSQL a ler ou escrever diretamente no arquivo. O arquivo deve ser acessível ao servidor, e o nome deve ser especificado sob o ponto de vista do servidor. Quando é especificado STDIN ou STDOUT, os dados são transmitidos através da conexão entre o cliente e o servidor.

Parâmetros

nome_da_tabela

O nome de uma tabela existente (opcionalmente qualificado pelo esquema).

coluna

Lista opcional das colunas a serem copiadas. Se não for especificada nenhuma lista de colunas, serão copiadas todas as colunas da tabela.

nome_do_arquivo

O nome do caminho absoluto do arquivo de entrada ou de saída.

STDIN

Especifica que a entrada vem do aplicativo cliente.

STDOUT

Especifica que a saída vai para o aplicativo cliente.

BINARY

Faz todos os dados serem armazenados ou lidos no formato binário, em vez de texto. Não é possível especificar as opções DELIMITER, NULL ou CSV no modo binário.

OIDS

Especifica que deve ser copiado o identificador do objeto (OID) de cada linha; é lançado um erro se for especificado OIDS para uma tabela que não possua OIDs.

delimitador

O caractere único que separa as colunas dentro de cada linha do arquivo. No modo texto o padrão é o caractere de tabulação, e no modo CSV o padrão é a vírgula.

cadeia_de_caracteres_nula

A cadeia de caracteres que representa o valor nulo. No modo texto o padrão é \N (contrabarra-N), e no modo CSV o padrão é o valor vazio sem os caracteres de demarcação. Pode-se preferir a cadeia de caracteres vazia, mesmo no modo texto, para os casos onde não se deseja fazer distinção entre nulos e cadeias de caracteres vazias.

Nota: Quando se utiliza o COPY FROM qualquer item de dado que corresponda a esta cadeia de caracteres é armazenado como um valor nulo e, portanto, deve haver certeza que está sendo usada a mesma cadeia de caracteres que foi utilizada com COPY TO.

CSV

Seleciona o modo valor separado por vírgula (CSV).

demarcador

Especifica o caractere demarcador (quotation character) no modo CSV. Aspas por padrão.

escape

Especifica o caractere que deve preceder o valor do caractere de dado QUOTE no modo CSV. O padrão é o mesmo valor de QUOTE (geralmente aspas).

FORCE QUOTE

No modo COPY TO CSV força a utilização do demarcador em todos os valores diferentes de NULL, em cada uma das colunas especificadas. A saída NULL nunca é demarcada.

FORCE NOT NULL

No modo COPY TO CSV processa cada coluna especificada como se estivesse demarcada e, portanto, não sendo um valor NULL. Para a cadeia de caracteres nula padrão no modo CSV (''), faz com que os valores ausentes sejam entrados como cadeias de caracteres de comprimento zero.

Observações

O comando COPY só pode ser utilizado em tabelas, não podendo ser utilizado em visões.

A palavra chave BINARY faz todos os dados serem armazenados/lidos no formato binário em vez de texto. É um pouco mais rápido que o modo texto normal, mas o arquivo no formato binário é menos portável entre arquiteturas de máquinas e versões do PostgreSQL.

É necessário possuir o privilégio de seleção na tabela cujos valores são lidos pelo COPY TO, e o privilégio inserção na tabela onde os valores são inseridos pelo COPY FROM.

Os arquivos declarados no comando COPY são lidos ou escritos diretamente pelo servidor, e não pelo aplicativo cliente. Portanto, devem residir ou serem acessíveis pela máquina servidora de banco de dados, e não pela estação cliente. Os arquivos devem ser acessíveis e poderem ser lidos ou escritos pelo usuário do PostgreSQL (o ID do usuário sob o qual o servidor executa), e não pelo cliente. O COPY especificando um nome de arquivo só é permitido aos superusuários do banco de dados, porque permite ler e escrever em qualquer arquivo que o servidor possua privilégio de acesso.

Não deve ser confundido o comando COPY com a instrução \copy do psql. A instrução \copy executa COPY FROM STDIN ou COPY TO STDOUT e, portanto, lê/grava os dados em um arquivo acessível ao cliente psql. Por esta razão, quando se utiliza \copy a acessibilidade e os direitos de acesso ao arquivo dependem do cliente, e não do servidor.

Recomenda-se que o nome do arquivo utilizado no comando COPY seja sempre especificado como um caminho absoluto, o que é exigido pelo servidor no caso do COPY TO, mas para o COPY FROM existe a opção de ler um arquivo especificado pelo caminho relativo. O caminho é interpretado com relação ao diretório de trabalho do processo servidor (normalmente o diretório de dados do agrupamento), e não o diretório de trabalho do cliente.

O comando COPY FROM chama os gatilhos e as restrições de verificação da tabela de destino. Entretanto, não chama as regras.

A entrada e a saída do COPY são afetadas por DateStyle. Para garantir a portabilidade com outras instalações do PostgreSQL, que podem utilizar definições para DateStyle diferentes do padrão, deve ser definido DateStyle como ISO antes de usar COPY TO.

O COPY pára de executar no primeiro erro, o que não deve causar problemas no caso do COPY TO, mas a tabela de destino já terá recebido as linhas anteriores no caso do COPY FROM. Estas linhas não são visíveis nem acessíveis, mas ainda assim ocupam espaço em disco, podendo causar o desperdício de uma quantidade considerável de espaço em disco se o erro ocorrer durante a cópia de uma grande quantidade de dados. Deve ser executado o comando VACUUM para recuperar o espaço desperdiçado.

Formatos dos arquivos

Formato texto

Quando o comando COPY é utilizado sem as opções BINARY ou CSV, os dados são lidos ou escritos em um arquivo texto com uma linha para cada linha da tabela. As colunas de cada linha são separadas pelo caractere delimitador. Os valores das colunas são cadeias de caracteres geradas pela função de saída, ou aceitas pela função de entrada, do tipo de dado de cada atributo. A cadeia de caracteres nula especificada é utilizada no lugar das colunas que são nulas. O comando COPY FROM lança um erro se alguma linha do arquivo de entrada possuir mais, ou menos, colunas que o esperado. Se for especificado OIDS, então o OID é lido ou escrito como a primeira coluna, antecedendo as colunas de dado do usuário.

O fim dos dados pode ser representado por uma única linha contendo apenas contrabarra-ponto (\.). A marca de fim-de-dados não é necessária ao ler de um arquivo, porque o fim-de-arquivo serve perfeitamente bem; é necessária apenas ao copiar dados de/para aplicativos cliente quando for utilizado um protocolo cliente anterior ao 3.0.

Podem ser utilizados caracteres contrabarra (\) nos dados do comando COPY para evitar que caracteres de dados sejam interpretados como delimitadores de linha ou de coluna. Em particular, os seguintes caracteres devem ser precedidos por uma contrabarra se fizerem parte do valor de uma coluna: a própria contrabarra, a nova-linha (LF), o retorno-do-carro (CR) e o caractere delimitador corrente.

A cadeia de caracteres nula especificada é enviada pelo comando COPY TO sem adição de contrabarras; inversamente, o comando COPY FROM verifica a entrada com relação à cadeia de caracteres nula antes de remover as contrabarras. Portanto, uma cadeia de caracteres nula, como o \N, não pode ser confundida com o valor de dado \N (que seria representado por \\N).

São reconhecidas pelo comando COPY FROM as seguintes seqüências especiais de contrabarra :

Seqüência Representa
\b Retorna apagando (Backspace) (ASCII 8)
\f Avanço do formulário (Form feed) (ASCII 12)
\n Nova-linha (Newline) (ASCII 10)
\r Retorno do carro (Carriage return) (ASCII 13)
\t Tabulação (ASCII 9)
\v Tabulação vertical (ASCII 11)
\dígitos A contrabarra seguida por um a três dígitos octais especifica o caractere com este código numérico

Atualmente o COPY TO não produz seqüências do tipo contrabarra dígitos-octais, mas utiliza as outras seqüências de contrabarra listadas acima para estes caracteres de controle.

Qualquer outro caractere precedido por contrabarra que não tenha sido mencionado na tabela acima é interpretado como representando a si próprio. Entretanto, deve-se tomar cuidado ao adicionar contrabarras sem necessidade, uma vez que isto poderá produzir acidentalmente uma cadeia de caracteres correspondendo à marca de fim-de-dados (\.), ou a cadeia de caracteres nula (\N por padrão). Estas cadeias de caracteres são reconhecidas antes de ser feito qualquer outro processamento da contrabarra.

É altamente recomendado que os aplicativos que geram dados para o comando COPY convertam os caracteres de nova-linha e de retorno-de-carro presentes nos dados nas seqüências \n e \r, respectivamente. Atualmente é possível representar retorno-de-carro nos dados por contrabarra e retorno-de-carro, e representar nova-linha nos dados por contrabarra e nova-linha. Entretanto, estas representações poderão não ser aceitas nas versões futuras. São, também, altamente vulneráveis à alteração quando o arquivo do COPY é transferido entre máquinas diferentes; por exemplo, do Unix para o Windows, ou vice-versa.

O comando COPY TO termina cada linha pelo caractere de nova-linha ("\n"), no estilo Unix. Os servidores executando no Microsoft Windows em vez disto geram retorno-de-carro/nova-linha ("\r\n"), mas somente no COPY para um arquivo no servidor; para manter a consistência entre as plataformas, COPY TO STDOUT sempre envia "\n", independentemente da plataforma do servidor. O comando COPY FROM consegue tratar linhas terminando por nova-linha, retorno-de-carro, ou retorno-de-carro/nova-linha. Para reduzir o risco de erro devido a caracteres de nova-linha ou de retorno-de-carro sem contrabarra que fazem parte dos dados, o COPY FROM reclama se o final de todas as linhas de entrada não forem idênticos.

Formato CSV

Este formato é utilizado para importar e exportar arquivos no formato Valor Separado por Vírgula (Comma Separated ValueCSV) usado por vários outros programas, como as planilhas eletrônicas. Em vez do escape utilizado pelo modo texto padrão do PostgreSQL, este formato gera e reconhece o mecanismo de escape comum do CSV.

Em cada registro os valores são separados pelo caractere DELIMITER. Se o valor contiver o caractere delimitador, o caractere QUOTE, a cadeia de caracteres NULL, um caractere de retorno-de-carro ou de nova-linha, então todo o valor recebe como prefixo e sufixo o caractere QUOTE, e qualquer ocorrência do caractere QUOTE ou do caractere ESCAPE dentro do valor é precedida pelo caractere de escape. Também pode ser utilizado FORCE QUOTE para obrigar a colocação de demarcadores nos valores diferentes de NULL em determinadas colunas.

O formato CSV não possui uma forma padronizada para distinguir entre o valor NULL e uma cadeia de caracteres vazia. O COPY do PostgreSQL trata isto através dos demarcadores. O valor NULL é escrito como a cadeia de caracteres NULL sem demarcadores, enquanto o valor de dado correspondendo à cadeia de caracteres NULL é escrito entre demarcadores. Portanto, usando a configuração padrão, o valor NULL é escrito como uma cadeia de caracteres vazia sem os caracteres demarcadores, enquanto uma cadeia de caracteres vazia é escrita entre aspas (""). A leitura dos valores segue regras semelhantes. Pode ser utilizado FORCE NOT NULL para inibir comparações de entrada NULL para determinadas colunas.

Nota: O modo CSV tanto reconhece quanto gera arquivos CSV com valores entre caracteres de demarcador contendo retorno-de-carro e nova-linha embutidos. Portanto, os arquivos não são exatamente uma linha para cada linha da tabela como nos arquivos do modo texto. Entretanto, o PostgreSQL rejeita a entrada para o COPY se houver embutida em algum campo uma seqüência de caracteres de fim de linha que não corresponda à convenção de fim de linha usada no próprio arquivo CSV. Geralmente é mais seguro importar dados contendo caracteres de fim de linha usando os formatos texto ou binário em vez do CSV.

Nota: Muitos programas produzem arquivos CSV estranhos e ocasionalmente maldosos; portanto, este formato de arquivo é mais uma convenção do que um padrão. Por isso, podem ser encontrados arquivos que não podem ser importados utilizando este mecanismo, e o COPY pode produzir arquivos que outros programas não conseguem processar.

Formato Binário

O formato do arquivo usado pelo COPY BINARY mudou no PostgreSQL v7.4. O novo formato consiste em um cabeçalho do arquivo, zero ou mais tuplas contendo os dados das linhas, e um rodapé do arquivo. Os cabeçalhos e os dados estão agora na ordem de bytes da rede.

Cabeçalho do Arquivo

O cabeçalho do arquivo é formado por 15 bytes para campos fixos, seguidos por uma área de extensão do cabeçalho de comprimento variável. Os campos fixos são:

Assinatura

A seqüência de 11 bytes PGCOPY\n\377\r\n\0 — observe que o byte zero é uma parte requerida da assinatura (A assinatura foi projetada para permitir a fácil identificação de arquivos modificados por uma transferência de dados não apropriada. Esta assinatura é modificada por filtros de tradução de fim de linha, bytes zero suprimidos, bits altos suprimidos, ou mudanças de paridade).

Campo de sinalizadores

Inteiro de 32 bits, máscara de bits, indicando aspectos importantes do formato do arquivo. Os bits são numerados de 0 (LSB) a 31 (MSB). Deve ser observado que este campo é armazenado na ordem de bytes da rede (byte mais significativo primeiro), assim como todos os campos inteiros utilizados no formato do arquivo. Os bits 16-31 são reservados para indicar questões críticas do formato do arquivo; a leitura deve ser interrompida se for encontrado neste intervalo um bit definido não esperado. Os bits 0-15 são reservados para sinalizar questões relativas a compatibilidade com formatos anteriores; a leitura deve simplesmente ignorar qualquer bit definido não esperado neste intervalo. Atualmente somente está definido um bit sinalizador, os demais devem ser zero:

Bit 16

Se for 1, os OIDs estão incluídos nos dados; se for 0, não.

Comprimento da área de extensão do cabeçalho

Inteiro de 32 bits, contendo o comprimento em bytes do restante do cabeçalho, não se incluindo. Atualmente é igual a zero, e a primeira tupla vem imediatamente em seguida. Mudanças futuras no formato poderão permitir a presença no cabeçalho de dados adicionais. A leitura deve simplesmente pular qualquer dado na extensão do cabeçalho que não souber o que fazer com o mesmo.

A área de extensão do cabeçalho foi concebida para conter uma seqüência de blocos auto-identificadores. O campo de sinalizadores não tem por finalidade informar aos leitores o que existe na área de extensão. O projeto específico do conteúdo da extensão do cabeçalho foi deixado para uma versão futura.

Este projeto permite adições de cabeçalhos compatíveis com os anteriores (adicionar blocos de extensão de cabeçalho, ou definir bits sinalizadores de baixa-ordem), tanto quanto mudanças não compatíveis com os anteriores (definir bits sinalizadores de alta-ordem para sinalizar estas mudanças, e adicionar dados de apoio à área de extensão se for necessário).

Tuplas

Cada tupla começa por um inteiro de 16 bits, que é o contador do número de campos na tupla; atualmente todas as tuplas da tabela possuem o mesmo contador, mas isto poderá não ser verdade para sempre. Depois, repetido para cada campo da tupla, existe uma palavra com comprimento com 32 bits seguida por este número de bytes de dados do campo; a palavra com comprimento não se inclui, podendo ser zero. Como caso especial, -1 indica que o valor do campo é nulo, e nenhum byte de valor vem em seguida.

Não existe nenhum preenchimento de alinhamento ou qualquer outro dado adicional entre os campos.

Atualmente é assumido que todos os valores dos dados em um arquivo COPY BINARY estão no formato binário (código de formatação um). Preve-se que uma extensão futura poderá adicionar um campo de cabeçalho permitindo que sejam especificados códigos de formatação por coluna.

Para determinar o formato binário apropriado para os dados da tupla deve ser consultado o código fonte do PostgreSQL, em particular as funções *send e *recv para o tipo de dado de cada coluna (normalmente estas funções se encontram no diretório src/backend/utils/adt/ da distribuição do código fonte).

Se os OIDs estiverem incluídos no arquivo, o campo OID vem imediatamente após palavra contador de número de campos. É um campo normal, exceto por não estar incluído no contador do número de campos. Em particular possui uma palavra comprimento — isto permite tratar OIDs de 4-bytes versus OIDs de 8-bytes sem muita dificuldade e, também, permite que os OIDs sejam mostrados como nulo se por acaso for desejado.

Rodapé do Arquivo

O rodapé do arquivo consiste de um inteiro de 16-bits contendo -1. É facilmente distinguível da palavra contador do número de campos da tupla.

A leitura deve relatar um erro se a palavra contador do número de campos não for -1 nem for o número de colunas esperado. Isto permite uma verificação adicional com relação à perda de sincronização com os dados.

Exemplos

O exemplo a seguir copia uma tabela para o cliente utilizando a barra vertical (|) como delimitador de campo:

COPY paises TO STDOUT WITH DELIMITER '|';

Para copiar os dados de um arquivo para a tabela paises:

COPY paises FROM '/usr1/proj/bray/sql/dados_dos_paises';

Abaixo estão mostrados dados adequados para serem copiados para uma tabela a partir da STDIN:

AF      AFGHANISTAN
AL      ALBANIA
DZ      ALGERIA
ZM      ZAMBIA
ZW      ZIMBABWE

Deve ser observado que em cada linha o espaço em branco é, na verdade, o caractere de tabulação.

Abaixo estão os mesmos dados escritos no formato binário. Os dados mostrados foram filtrados utilizando o utilitário do Unix od -c. A tabela possui três colunas: a primeira é do tipo char(2); a segunda é do tipo text; a terceira é do tipo integer. Todas as linhas possuem o valor nulo na terceira coluna.

0000000   P   G   C   O   P   Y  \n 377  \r  \n  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0 003  \0  \0  \0 002   A   F  \0  \0  \0 013   A
0000040   F   G   H   A   N   I   S   T   A   N 377 377 377 377  \0 003
0000060  \0  \0  \0 002   A   L  \0  \0  \0 007   A   L   B   A   N   I
0000100   A 377 377 377 377  \0 003  \0  \0  \0 002   D   Z  \0  \0  \0
0000120 007   A   L   G   E   R   I   A 377 377 377 377  \0 003  \0  \0
0000140  \0 002   Z   M  \0  \0  \0 006   Z   A   M   B   I   A 377 377
0000160 377 377  \0 003  \0  \0  \0 002   Z   W  \0  \0  \0  \b   Z   I
0000200   M   B   A   B   W   E 377 377 377 377 377 377

No próximo exemplo [1] é utilizado o comando COPY, chamado a partir do psql, para copiar as últimas cinco linhas do arquivo /tmp/linhas.dat, que contém três colunas separadas por |, para a primeira, a segunda e a quarta colunas de uma tabela de quatro colunas. A tabela foi criada através do comando:

CREATE TABLE linhas (
coluna1 TEXT PRIMARY KEY,
coluna2 TEXT,
coluna3 TEXT,
coluna4 TEXT);

O conteúdo do arquivo carregado está mostrado abaixo:

# cat /tmp/linhas.dat
linha1a|linha1b|linha1d
linha2a|linha2b|linha2d
linha3a|linha3b|linha3d
linha4a|linha4b|linha4d
linha5a|linha5b|linha5d
linha6a|linha6b|linha6d
linha7a|linha7b|linha7d
linha8a|linha8b|linha8d

E o comando utilizado para copiar os dados do arquivo para a tabela foi:

tail --lines=5 /tmp/linhas.dat | psql -U teste teste -c \
"COPY linhas(coluna1,coluna2,coluna4) FROM STDIN WITH DELIMITER '|'"

Como resultado os seguintes dados foram incluídos na tabela:

SELECT * FROM linhas;

 coluna1 | coluna2 | coluna3 | coluna4
---------+---------+---------+---------
 linha4a | linha4b |         | linha4d
 linha5a | linha5b |         | linha5d
 linha6a | linha6b |         | linha6d
 linha7a | linha7b |         | linha7d
 linha8a | linha8b |         | linha8d
(5 linhas)

Compatibilidade

Não existe o comando COPY no padrão SQL.

A sintaxe mostrada abaixo era utilizada nas versões do PostgreSQL anteriores a 7.3, sendo ainda aceita:

COPY [ BINARY ] nome_da_tabela [ WITH OIDS ]
    FROM { 'nome_do_arquivo' | STDIN }
    [ [USING] DELIMITERS 'delimitador' ]
    [ WITH NULL AS 'cadeia_de_caracteres_nula' ]

COPY [ BINARY ] nome_da_tabela [ WITH OIDS ]
    TO { 'nome_do_arquivo' | STDOUT }
    [ [USING] DELIMITERS 'delimitador' ]
    [ WITH NULL AS 'cadeia_de_caracteres_nula' ]

Notas

[1]

Este exemplo foi escrito pelo tradutor, não fazendo parte do manual original.

SourceForge.net Logo CSS válido!