Arquivos no formato XLS legado (Excel 97-2003) representam um dos maiores gargalos de integração em ambientes corporativos modernos. Diferente dos formatos baseados em XML (.xlsx), o XLS utiliza o formato binário BIFF8, que frequentemente apresenta incompatibilidades de encoding, limites rígidos de linhas e tipos de dados não padronizados. Quando o objetivo é transferir esses registros para um banco de dados relacional (como PostgreSQL, MySQL ou SQL Server), o processo manual é inviável e propenso a corrupções de integridade referencial.
A abordagem técnica correta consiste em construir um pipeline de extração, tratamento e carga (ETL) em Python, garantindo performance, tipagem estrita e idempotência.
1. Leitura Eficiente do Formato BIFF8 (.xls)
A biblioteca moderna padrão para leitura de Excel em Python é o openpyxl, porém ela não suporta arquivos .xls binários. Para este cenário, a combinação entre pandas e o motor xlrd (versões compatíveis com arquivos legados) ou ferramentas de baixo nível em Rust via bindings Python é a solução ideal para extrair os dados sem perdas.
python
import pandas as pd
def carregarxlslegado(caminhoarquivo: str, aba: str = 0) -> pd.DataFrame:
# O engine ‘xlrd’ é mandatório para arquivos binários .xls
df = pd.readexcel(caminhoarquivo, sheetname=aba, engine=’xlrd’)
# Normalização de nomes de colunas: snake_case e remoção de caracteres especiais
df.columns = (
df.columns.str.strip()
.str.lower()
.str.replace(' ', '_')
.str.replace(r'[^a-zA-Z0-9_]', '', regex=True)
)
return df
2. Sanitização e Mapeamento de Tipos
Planilhas XLS antigas frequentemente misturam textos em colunas numéricas, datas mal formatadas e múltiplos formatos de valores nulos (ex: ‘N/A’, ‘-‘, ‘NULL’). Antes de tentar qualquer inserção SQL, os dados devem ser limpos em memória:
- Datas: Conversão explícita com
pd.to_datetime(errors='coerce')para evitar erros no parser do SQL. - Valores Numéricos: Substituição de separadores de milhar e decimais antes do cast para
floatouint. - Valores Nulos: Conversão de valores vazios para
None, garantindo que o driver SQL insira o literalNULLem vez de strings vazias.
3. Carga Otimizada via SQLAlchemy em Lotes (Batch Processing)
Inserir linha por linha gera um overhead de rede insustentável. A conexão deve ser estabelecida via SQLAlchemy, utilizando inserções em lote (chunksize) dentro de uma transação única.
python
from sqlalchemy import create_engine, text
DATABASEURL = “postgresql://usuario:senha@localhost:5432/meubanco”
engine = createengine(DATABASEURL, poolpre_ping=True)
def persistirdados(df: pd.DataFrame, tabeladestino: str):
with engine.begin() as conexao:
# Carga em lotes para minimizar consumo de memória e chamadas de rede
df.tosql(
name=tabeladestino,
con=conexao,
ifexists=’append’,
index=False,
chunksize=1000,
method=’multi’
)
print(f”{len(df)} registros migrados com sucesso para {tabeladestino}.”)
4. Boas Práticas: Tabela de Staging e Validação Final
Como especialista em IA e engenharia de dados, costumo desenhar pipelines onde os dados legados nunca entram diretamente na tabela transacional final. O fluxo seguro envolve:
- Staging Table: Inserção em uma tabela temporária com schemas flexíveis.
- Sanitização via SQL: Execução de scripts SQL de validação de chaves estrangeiras e unicidade.
- Upsert Final: Migração da staging para a tabela definitiva com cláusulas
ON CONFLICT DO UPDATE(ouMERGE), evitando duplicidades caso o processo precise ser reexecutado.
Automatize Seus Fluxos de Dados Legados
Migrar dados legados de planilhas obsoletas para arquiteturas SQL robustas é o primeiro passo para desbloquear o valor analítico e alimentar modelos de inteligência artificial na sua empresa.
Se você possui bases legadas em XLS, CSVs inconsistentes ou bancos legados que precisam ser integrados com confiabilidade e velocidade, entre em contato para estruturar uma solução de engenharia de dados sob medida para a sua operação.


