1.11. Importando e Exportando Dados
O PostgreSQL fornece um comando para uso via SQL chamado COPY
que permite mover dados de arquivos para tabelas do banco de dados e vice-versa. Este comando trata arquivos no formato texto, CSV e binários. As ferramentas clientes, como o psql e o pgAdmin, fornecem recursos que utilizam esse comando para copiar dados entre o cliente e o servidor. Nesta seção, vamos explorar esse comando de importação e exportação de dados diretamente do lado servidor bem como através das ferramentas psql, com o meta-comando \copy
, e pela interface gráfica do pgAdmin.
1.11.1. Importando arquivos CSV
Considere o arquivo glebas-2024-subconjunto.csv
, mostrado parcialmente abaixo, e que contém dados sobre 50 glebas de operações de crédito rural com recursos públicos do ano de 2024.
#REF_BACEN;NU_ORDEM;NU_INDICE;GT_GEOMETRIA
517254553;1;0;POLYGON ((-43.902034 -21.309695999999899 0,-43.90041 -21.308319 0,-43.898786999999899 -21.306943 0,-43.89898 -21.30575 0,-43.899172 -21.304557 0,-43.900615 -21.305241 0,-43.902057 -21.305924 0,-43.902152 -21.306318 0,-43.902247 -21.306712 0,-43.902342 -21.307106 0,-43.902437 -21.3075 0,-43.902034 -21.309695999999899 0))
517254555;1;0;POLYGON ((-49.406416 -15.845366 0,-49.406251 -15.846175 0,-49.406311 -15.846967 0,-49.406327 -15.847805 0,-49.405669 -15.847882 0,-49.404994 -15.847869 0,-49.404335 -15.847872 0,-49.403678 -15.847847 0,-49.403047 -15.847823 0,-49.40297 -15.845221 0,-49.406416 -15.845366 0))
517254557;1;0;POLYGON ((-62.420199 -10.651255 0,-62.420073 -10.65143 0,-62.41997 -10.65159 0,-62.419887 -10.651774 0,-62.419804 -10.652062 0,-62.41973 -10.652269 0,-62.419648 -10.652388 0,-62.419449 -10.652637 0,-62.41927 -10.652819 0,-62.419156 -10.652982 0,-62.419022 -10.653222 0,-62.418862 -10.653378 0,-62.418493 -10.653694 0,-62.41817 -10.653956 0,-62.417853 -10.654275 0,-62.416715 -10.653373 0,-62.415766 -10.652611 0,-62.415485 -10.652344 0,-62.415586 -10.65204 0,-62.4157 -10.651831 0,-62.415747 -10.651675 0,-62.415793 -10.651568 0,-62.415876 -10.651453 0,-62.416019 -10.651198 0,-62.416251 -10.650926 0,-62.416422 -10.650894 0,-62.41661 -10.650804 0,-62.416699 -10.650682 0,-62.416753 -10.650447 0,-62.416723 -10.650269 0,-62.416601 -10.650093 0,-62.416297 -10.649946 0,-62.416095 -10.649979 0,-62.415919 -10.65011 0,-62.415839 -10.650227 0,-62.415796 -10.650383 0,-62.415486 -10.650751 0,-62.415256 -10.651139 0,-62.415105 -10.651426 0,-62.415071 -10.651535 0,-62.414964 -10.651633 0,-62.414955 -10.651764 0,-62.414883 -10.651885 0,-62.414273 -10.651385 0,-62.413518 -10.650769 0,-62.413696 -10.650582 0,-62.413967 -10.650394 0,-62.414198 -10.650153 0,-62.414349 -10.649975 0,-62.414591 -10.649637 0,-62.414907 -10.649308 0,-62.415441 -10.648888 0,-62.415825 -10.648517 0,-62.416056 -10.648325 0,-62.416266 -10.648118 0,-62.416375 -10.648104 0,-62.417325 -10.648942 0,-62.418916 -10.650218 0,-62.419201 -10.650453 0,-62.419812 -10.65092 0,-62.420199 -10.651255 0))
517254558;1;0;POLYGON ((-47.621074 -23.734939 0,-47.620834 -23.73527 0,-47.620592 -23.735756 0,-47.619826 -23.736261 0,-47.618565 -23.737299 0,-47.618107 -23.736539 0,-47.619078 -23.735883 0,-47.618975 -23.735738 0,-47.618813 -23.735433 0,-47.618819 -23.735323 0,-47.618948 -23.734881999999899 0,-47.621517 -23.734656 0,-47.621074 -23.734939 0))
517254563;1;0;POLYGON ((-55.290694 -23.89695 0,-55.288356 -23.89928 0,-55.286018 -23.901611 0,-55.285032 -23.900872 0,-55.28454 -23.900503 0,-55.284047 -23.900134 0,-55.285116 -23.899145 0,-55.286185 -23.898156 0,-55.287254 -23.897167 0,-55.288323 -23.896178 0,-55.289508 -23.896564 0,-55.290694 -23.89695 0))
517254564;1;0;POLYGON ((-36.458228 -9.08855 0,-36.458088 -9.088049 0,-36.458134999999899 -9.087302 0,-36.458305 -9.086873 0,-36.460358 -9.087847 0,-36.460551 -9.088001 0,-36.460204 -9.088266 0,-36.459961 -9.088575 0,-36.45982 -9.08883 0,-36.459644 -9.089371 0,-36.459839 -9.090408 0,-36.459264 -9.089842 0,-36.458593 -9.089071 0,-36.458228 -9.08855 0))
517254568;1;0;POLYGON ((-42.110267 -11.252986 0,-42.108296 -11.253158 0,-42.10797 -11.252483 0,-42.107637 -11.252058 0,-42.107678 -11.251791 0,-42.10772 -11.251523 0,-42.107871 -11.251082 0,-42.108022 -11.250641 0,-42.108529 -11.250789 0,-42.109036 -11.250938 0,-42.11037 -11.250975 0,-42.110267 -11.252986 0))
517254568;2;0;POLYGON ((-42.110267 -11.252986 0,-42.108296 -11.253158 0,-42.10797 -11.252483 0,-42.107637 -11.252058 0,-42.107678 -11.251791 0,-42.10772 -11.251523 0,-42.107871 -11.251082 0,-42.108022 -11.250641 0,-42.108529 -11.250789 0,-42.109036 -11.250938 0,-42.11037 -11.250975 0,-42.110267 -11.252986 0))
517254570;1;0;POLYGON ((-50.082767 -15.335757 0,-50.08392 -15.339846 0,-50.082349 -15.339943 0,-50.082157 -15.340231 0,-50.081835 -15.340382 0,-50.081611 -15.340109 0,-50.081518 -15.339881 0,-50.08134 -15.339756 0,-50.080969 -15.339759 0,-50.08089 -15.339414 0,-50.080771 -15.339335 0,-50.080738 -15.33908 0,-50.080461 -15.339047 0,-50.080257 -15.33885 0,-50.080127 -15.338278 0,-50.079809 -15.338278 0,-50.07938 -15.338172 0,-50.078913 -15.337195 0,-50.07964 -15.336971 0,-50.080047 -15.336793 0,-50.080515 -15.336557 0,-50.080796 -15.336559 0,-50.081031 -15.336334 0,-50.081094 -15.336121 0,-50.081662 -15.33573 0,-50.081971 -15.335648 0,-50.082388 -15.335649 0,-50.082767 -15.335757 0))
517254572;1;0;POLYGON ((-49.957618 -19.52558 0,-49.953671 -19.528482 0,-49.949725 -19.531385 0,-49.946955 -19.530209 0,-49.94557 -19.52962 0,-49.944185 -19.529032 0,-49.946213 -19.527215 0,-49.948241 -19.525398 0,-49.950269 -19.523581 0,-49.952297 -19.521765 0,-49.954957 -19.523672 0,-49.957618 -19.52558 0))
Nota
Os dados apresentados nesse arquivo foram extraídos do Portal do Banco Central do Brasil - Tabelas e Microdados do Crédito Rural e do Proagro.
Nota
O arquivo CSV completo com dados de 2024 pode ser baixado do seguinte link sicor_glebas_wkt_2024.gz
.
Repare que esse arquivo possui uma primeira linha com um cabeçalho, indicando as colunas presentes:
#REF_BACEN;NU_ORDEM;NU_INDICE;GT_GEOMETRIA
Os campos encontram-se separados pelo caractere ;
:
517254553;1;0;POLYGON ((-43.902034 -21.309695999999899, ...))
Para importar esse arquivo para o banco de dados usando o comando COPY
ou o metacomando \copy
, primeiro devemos criar uma tabela capaz de armazenar esses dados:
CREATE TABLE glebas
(
ref_bacen INTEGER,
nu_ordem INTEGER,
nu_indice INTEGER,
geom GEOMETRY(POLYGONZ, 4674)
);
Nota
Repare que não incluímos restrições na definição da tabela acima. Além disso, definimos nomes para os campos diferente dos que aparecem no cabeçalho do arquivo CSV.
1.11.1.1. Comando COPY
Para copiar o arquivo acima para a nova tabela criada, podemos utilizar o comando COPY
indicando na cláusula FROM
o caminho completo para que o servidor encontre o arquivo de dados, como mostrado abaixo:
COPY glebas(ref_bacen, nu_ordem, nu_indice, geom)
FROM '/data/glebas-2024-subconjunto.csv'
WITH (DELIMITER ';', FORMAT CSV, HEADER true);
Resultado:
COPY 50
No comando acima o nome da tabela para onde importaremos o dado é especificado logo após a palavra-chave COPY
. Se a tabela possuir colunas com tipos compatíveis com a mesma estrutura do arquivo CSV, então podemos omitir a lista de colunas, caso contrário, as colunas para as quais copiaremos os dados deverão aperecer entre parênteses. O caminho do arquivo CSV é colocado logo após a palavra-chave FROM
. Ao final do comando podemos especificar algumas opções, tais como: o delimitador de valores usado no arquivo (;
), o formato do arquivo (CSV
) e a presença de uma linha de cabeçalho no início do arquivo (HEADER
).
Se o comando acima for bem sucedido, você receberá uma mensagem indicando que 50
linhas foram copiadas para a tabela glebas
.
Nota
O exemplo acima também poderia ser realizado sem especificar as colunas da tabela de destino:
COPY glebas
FROM '/data/glebas-2024-subconjunto.csv'
WITH (DELIMITER ';', FORMAT CSV, HEADER true);
Dica
Para saber mais sobre o comando COPY
, consulte o manual do PostgreSQL na Seção COPY.
1.11.1.2. Usando o Meta-comando \copy
Um detalhe importante sobre o comando COPY
é que o arquivo de dados informado será lido pelo servidor PostgreSQL e, portanto, deve estar em um caminho acessível por ele. Isso significa que o arquivo precisa estar num sistema de arquivos acessível pelo servidor e que o usuário que executa o processo do servidor PostgreSQL precisará ter privilégios de leitura tanto no diretório quanto no arquivo de dados. Para relaxar essa restrição, as aplicações clientes, como o psql e o pgAdmin, utilizam uma variante desse comando que realiza a leitura e escrita para a entrada/saída padrão (COPY FROM STDIN
ou COPY TO STDOUT
).
No caso do psql, ele fornece um meta-comando chamado \copy
que pode ser usado de maneira análoga ao comando COPY
. A diferença essencial é que o \copy
realiza a leitura do arquivo no lado cliente, isto é, onde o psql é executado, e este é que de fato envia os dados pela rede de comunicação com o servidor PostgreSQL usando nos bastidores o comando COPY FROM STDIN
. Portanto, o exemplo da seção anterior poderia ser construído com o psql da seguinte forma:
\copy glebas FROM '/data/glebas-2024-subconjunto.csv' WITH (DELIMITER ';', FORMAT CSV, HEADER);
Dica
Uma forma simples de limpar o conteúdo de uma tabela é usar o comando TRUNCATE TABLE
, como mostrado abaixo:
TRUNCATE TABLE glebas;
Dica
Para saber mais sobre o meta-comando \copy
, veja o manual do psql.
1.11.1.3. Importando Dados pelo pgAdmin
Pela interface gráfica do pgAdmin é possível importar arquivos CSV. Ao selecionar a tabela para a qual se deseja copiar os dados, selecione o menu Import/Export Data...
, como mostrado na figura abaixo:
Na janela aberta, com a opção Import
selecionada, devemos indicar o arquivo a ser carregado:
O arquivo pode ser indicado de diversas formas. Uma delas consiste em fazer o upload do arquivo:
1.11.2. Exportando para Arquivos CSV
Vamos usar o meta-comando \copy
para exportar os dados da tabela glebas
para um arquivo denominado /data/glebas.csv
, onde a primeira linha será de cabeçalho e os valores em cada uma das linhas exportadas serão separados por ;
:
\copy glebas TO '/data/glebas.csv' WITH (DELIMITER ';', FORMAT CSV, HEADER true);
Resultado:
COPY 50
Podemos também exportar o resultado de uma consulta:
\copy (SELECT ref_bacen, nu_ordem, nu_indice, ST_AsText(ST_Force2D(geom)) FROM glebas WHERE ref_bacen = '517254582') TO '/data/gleba-517254582.csv' WITH (DELIMITER ';', FORMAT CSV, HEADER true);
Resultado:
COPY 1