ADBC ➔ PostgreSQL
Existem desafios para quem tem como fonte de dados arquivos "csv".
Possibilidade de erros na exportação e importação entre sistemas por
conta da formatação, codificação, delimitadores... além da falta de metadados
e compressão nativa, entre outros.
Em maio de 2024 comecei a procurar por dicas, melhores práticas,
casos de uso... até que encontrei um post de visual simples, em uma
página não tão famosa se comparada a outras.
"How fast can we process a CSV file"
de
Marc Garcia,
desenvolvedor do core do
pandas,
me mostrou que eu achava que sabia trabalhar com "csv"...
e com dados! Ele deixa dois avisos importantes:
"A velocidade de execução nem sempre é o que importa" e "Mais rápido para
um problema pode não ser para outro". Além disso indica o
parquet
como alternativa e apresenta:
PyArrow,
DuckDB,
DataFusion
e
Polars!
Todas essas tecnologias são incríveis, e nesse post mostrou que
Polars
tinha melhor desempenho. Mas, fiquei curioso sobre o
PyArrow...
e mais ainda quando descobri que o
Polars
usa
Arrow
debaixo do capô!
Depois dessas descobertas tinha metade dos problemas resolvidos:
eficiência para leitura, transformação e gravação dos dados.
Mas, precisaria carregar o arquivo
parquet
no
PostgreSQL,
já que onde trabalho queriam os dados no banco.
Então, como carregar os dados com eficiência também?
Encontrei soluções interessantes como
parquet_fdw
e
duckdb_fdw,
extensões de
FDW
(Foreign Data Wrappers) que permite que o
PostgreSQL
acesse e manipule dados de fontes remotas como se fossem tabelas
locais, nesse caso os arquivos
parquet.
Mas não consegui que funcionassem bem.
Então esbarrei em
"Performance Testing Postgres Inserts with Python"
de
Daniel Beach,
um Engenheiro de Dados na Rippleshot que relembra seu início de
carreira carregando dados por meio do
Python
no
PostgreSQL,
visando inserções com melhor desempenho.
Simples, objetivo e usando
psycopg2
!
E o código fica assim:
Como
mogrify
requer uma lista de tuplas, optei por
read_parquet
e
fetchall
para ler e realizar a conversão dos dados, sendo ambos de
DuckDB.
Em seguida uma compreensão de lista passando pelo
mogrify
que fornece uma string em bytes, mas decodificando a saída,
construindo uma string SQL formatada e preparada para ser executada.
Pronto, tudo funcionando bem!
Continuei explorando
PyArrow
e seria inevitável não conhecer
Arrow Database Connectivity!
ADBC
(...para os íntimos!) é um conjunto
de APIs e bibliotecas para acesso nativo do
Arrow
a banco de dados. Como ele tem um
driver para PostgreSQL
e eu estava transformando os dados em uma
pyarrow.Table,
percebi que não era preciso gerar o arquivo
parquet,
diminuindo uma etapa.
O novo código:
O método recebe três argumentos: os dados, o nome da tabela e do
schema
no banco. Agora sim!
Trabalhar com
PyArrow
pode não ser tão amigável como outras tecnologias e a
documentação
vai ser sua maior companheira, mas estou aprendendo muito e me
interessando cada vez mais.
Não fiz "benchmark" com outras tecnologias, mas o ganho de desempenho é notável!
Ahhh... não desisti do
parquet!
Tenho estudado sua utilização em
Object Storage
como
S3,
MinIO...
é uma tecnologia incrível!
E você, o que achou? Como faria?
Obrigado pela leitura.