(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como carregar dados para SQL Server num ETL (pandas)

João Barros 16 de July de 2026 4 min de leitura

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, SQLAlchemy e pyodbc.

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?