Como carregar dados para SQL Server num ETL (pandas)
A carga (Load) é a última etapa de um processo ETL: depois de extrair e transformar os dados, é preciso gravá-los numa tabela de destino. A forma mais comum de carregar dados para o SQL Server a partir de Python é escrever um DataFrame do pandas com o método to_sql e uma ligação criada com SQLAlchemy. Este guia mostra, passo a passo e com um exemplo simples, como o fazer de forma fiável.
Pré-requisitos
- Python 3 instalado e conhecimentos básicos de pandas.
- Uma base de dados SQL Server acessível e permissões para criar ou escrever numa tabela.
- O ODBC Driver for SQL Server (por exemplo, o Driver 18) instalado na máquina.
- As bibliotecas
pandas,SQLAlchemyepyodbc.
Passo 1: Instalar as bibliotecas
Começa por instalar as três bibliotecas necessárias. O pyodbc é o controlador que liga o Python ao SQL Server e o SQLAlchemy trata da ligação por cima dele. Usar o SQLAlchemy é a abordagem recomendada pelo pandas, porque simplifica a gestão da ligação.
pip install pandas sqlalchemy pyodbc
Passo 2: Preparar o DataFrame transformado
Imagina que já terminaste a fase de transformação e tens os dados prontos num DataFrame. Para o exemplo, vamos criar um pequeno conjunto de vendas já limpo.
import pandas as pd
df = pd.DataFrame({
"id_venda": [1, 2, 3],
"produto": ["Teclado", "Rato", "Monitor"],
"valor": [29.90, 15.50, 189.00],
})
print(df)
Repara que o índice do pandas (os números 0, 1, 2 à esquerda) não faz parte dos teus dados; no passo da carga vamos ignorá-lo.
Passo 3: Criar a ligação ao SQL Server
Com o SQLAlchemy, a ligação é definida por uma connection string. Cria um engine, que representa a ligação à base de dados de destino.
from sqlalchemy import create_engine
url = (
"mssql+pyodbc://user:password@server/database"
"?driver=ODBC+Driver+18+for+SQL+Server"
)
engine = create_engine(url, fast_executemany=True)
Substitui user, password, server e database pelos teus valores. A opção fast_executemany=True acelera bastante a inserção de muitas linhas no SQL Server. Boa prática: não deixes a palavra-passe escrita no código — lê-a de uma variável de ambiente (por exemplo, com os.environ) e constrói a partir daí a connection string.
Passo 4: Carregar os dados com to_sql
Agora é só escrever o DataFrame na tabela de destino. O método to_sql cria a tabela (se ainda não existir) e insere as linhas.
df.to_sql(
"vendas",
con=engine,
schema="dbo",
if_exists="append",
index=False,
chunksize=1000,
)
Vale a pena perceber cada parâmetro:
if_exists:"append"acrescenta às linhas existentes;"replace"apaga e recria a tabela;"fail"dá erro se a tabela já existir.index=False: evita gravar o índice do pandas como uma coluna extra.chunksize=1000: envia as linhas em lotes de 1000, o que ajuda quando o volume é grande.
Por omissão, o pandas deixa o SQLAlchemy escolher os tipos das colunas. Se precisares de controlo, usa o parâmetro dtype para indicar o tipo SQL de cada coluna. Nota ainda que, no SQL Server, deves acelerar a carga com fast_executemany=True no engine (Passo 3) em vez de method="multi", que pode esbarrar no limite de parâmetros.
Passo 5: Isolar a carga numa função
Num ETL a sério, convém isolar a carga numa função para a poderes reutilizar e testar com facilidade.
def carregar(df, tabela, engine):
df.to_sql(tabela, con=engine, schema="dbo",
if_exists="append", index=False, chunksize=1000)
print(f"Carregadas {len(df)} linhas para {tabela}.")
carregar(df, "vendas", engine)
Verificar o resultado
Para confirmar que os dados ficaram na tabela, lê-os de volta com o pandas e conta as linhas.
total = pd.read_sql("SELECT COUNT(*) AS n FROM dbo.vendas", engine)
print(total)
Se o número corresponder às linhas que carregaste, a fase de Load correu bem. Em alternativa, executa SELECT TOP 5 * FROM dbo.vendas no SQL Server Management Studio para veres os primeiros registos.
Conclusão
Já consegues carregar um DataFrame para o SQL Server e, com isso, fechar o ciclo Extract–Transform–Load em Python. A partir daqui, podes agendar o script, adicionar tratamento de erros e trocar o if_exists="append" por uma estratégia de upsert quando precisares de atualizar registos em vez de apenas inserir. Qual vai ser o próximo passo do teu ETL a automatizar?