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' ] ]

COPY nome_da_tabela [ ( coluna [, ...] ) ]
    TO { 'nome_do_arquivo' | STDOUT }
    [ [ WITH ] 
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimitador' ]
          [ NULL [ AS ] 'cadeia de caracteres nula' ] ]

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 uma lista de colunas for especificada, 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 STDIN ou STDOUT são especificados, 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
A lista opcional das colunas a serem copiadas. Se nenhuma lista for especificada, todas as colunas são utilizadas.
nome_do_arquivo
O nome do caminho absoluto do arquivo de entrada ou de saída.
STDIN
Especifica que a entrada vem da aplicação cliente.
STDOUT
Especifica que a saída vai para a aplicação 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 ou NULL no modo binário.
OIDS
Especifica que deve ser copiado o identificador interno do objeto (OID) de cada linha; é gerado um erro se OIDS for especificado para uma tabela que não possua OIDs.
delimitador
O caractere único que separa as colunas dentro de cada linha do arquivo. Por padrão o caractere de tabulação.
cadeia de caracteres nula
A cadeia de caracteres que representa o valor nulo. O padrão é "\N" (contrabarra-N). Pode-se preferir a cadeia de caracteres vazia, por exemplo.
Nota: No COPY FROM qualquer item de dado correspondendo a esta cadeia de caracteres é armazenado com o valor nulo e, portanto, deve haver certeza que está sendo utilizada a mesma cadeia de caracteres utilizada para fazer o COPY TO.

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 produzido no formato binário é menos portável entre arquiteturas de máquinas e versões do PostgreSQL.

É necessário possuir o privilégio SELECT na tabela cujos valores são lidos pelo COPY TO, e o privilégio INSERT 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 pela aplicação 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 com 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 confunda o comando COPY com a instrução \copy do psql. 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, a acessibilidade e os direitos de acesso ao arquivo dependem do cliente, e não do servidor, quando o \copy é utilizado.

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 (algum lugar abaixo do diretório de dados), e não relativo ao 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.

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 primeiras linhas 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 a opção BINARY, 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 nulas. O comando COPY FROM produz um erro se alguma linha do arquivo de entrada possuir mais, ou menos, colunas que o esperado. Se OIDS for especificado, 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 aplicações cliente quando for utilizado um protocolo cliente anterior ao 3.0.

Caracteres contrabarra (\) podem ser utilizados nos dados do comando COPY para evitar que caracteres dos 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 e o caractere delimitador corrente.

A cadeia de caracteres nula é enviada pelo COPY TO sem adição de contrabarras; inversamente, o 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).

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

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, tome cuidado ao adicionar contrabarras desnecessariamente uma vez que isto poderá, acidentalmente, produzir 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 ocorrer qualquer outro processamento da contrabarra.

É altamente recomendado que as aplicações que geram dados para o 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 podem não ser aceitas nas versões futuras. São, também, altamente vulneráveis à corrupção quando o arquivo do COPY é transferido entre máquinas diferentes; por exemplo, do Unix para o Windows, e 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 gera "\n", independentemente da plataforma do servidor. O comando COPY FROM pode 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 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 agora são enviados na ordem de byte 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 — Deve ser observado que o byte zero é uma parte requerida da assinatura (A assinatura foi projetada para permitir a fácil identificação de arquivos corrompidos 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 inteiro 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 um bit definido não esperado neste intervalo. Os bits 0-15 são reservados para sinalizar questões de formato anteriores-compatíveis; a leitura deve simplesmente ignorar qualquer bit definido não esperado neste intervalo. Atualmente somente um bit sinalizador está definido, 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 o segue imediatamente. Mudanças futuras no formato poderão permitir dados adicionais estarem presentes no cabeçalho. 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 tanto 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), 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 pode não ser verdade para sempre. Então, para cada campo da tupla, existe a informação do comprimento com 32 bits, seguida por esta quantidade de bytes de dados do campo (a informação do comprimento não se inclui, podendo ser zero). Como caso especial, -1 informa o valor de um campo nulo, e nenhum byte de valor vem a seguir.

Não existe nenhum enchimento de alinhamento ou qualquer outro dado extra 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). É previsto que uma extensão futura poderá adicionar um campo de cabeçalho permitindo que os códigos de formatação sejam especificados 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 forem incluídos no arquivo, o campo OID segue imediatamente a informação contador do número de campos. É um campo normal, exceto que não está incluído no contador do número de campos. Em particular possui uma informação de comprimento — permitindo tratar OIDs de 4-bytes versus 8-bytes sem muita dificuldade e, também, permitindo os OIDs serem mostrados como nulo se por acaso for desejado.

Rodapé do Arquivo

O rodapé do arquivo consiste numa informação, inteiro de 16 bits, contendo -1, facilmente distinguível da informação contador do número de campos da tupla.

A leitura deve relatar um erro se a informação contador do número de campos não for -1 nem for o número esperado de colunas. Isto permite uma verificação extra 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á mostrado um exemplo contendo dados apropriados para serem copiados a partir da STDIN:

AF      AFGHANISTAN
AL      ALBANIA
DZ      ALGERIA
ZM      ZAMBIA
ZW      ZIMBABWE

Deve ser observado que o espaço em branco em cada linha é, 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 a primeira, a segunda e a quarta colunas de uma tabela de quatro colunas, a partir da quarta linha do arquivo /tmp/linhas.dat. 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 +4 /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 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