---
title: "Python e DuckDB: Análise de Dados Ultrarrápida — 2026 | python.dev.br"
url: "https://python.dev.br/blog/python-e-duckdb-analytics/"
markdown_url: "https://python.dev.br/blog/python-e-duckdb-analytics.MD"
description: "Aprenda a usar DuckDB com Python para análise de dados local ultrarrápida. SQL direto em Pandas, Parquet e CSV sem servidor — exemplos práticos."
date: "2026-03-29"
author: "Equipe python.dev.br"
---

# Python e DuckDB: Análise de Dados Ultrarrápida — 2026 | python.dev.br

Aprenda a usar DuckDB com Python para análise de dados local ultrarrápida. SQL direto em Pandas, Parquet e CSV sem servidor — exemplos práticos.


Se você trabalha com análise de dados em Python, provavelmente já passou por situações em que o [Pandas](/blog/introducao-ao-pandas/) ficava lento demais para datasets grandes, mas subir um banco de dados completo parecia exagero. É exatamente nesse espaço que o **DuckDB** brilha — um banco de dados analítico embutido, sem servidor, que roda SQL diretamente em arquivos CSV, Parquet e até DataFrames do Pandas.

Neste artigo, vamos explorar como usar DuckDB com Python, desde a instalação até consultas avançadas, com exemplos práticos para o dia a dia.

## O Que É o DuckDB

O DuckDB é um banco de dados OLAP (Online Analytical Processing) embutido, projetado para cargas de trabalho analíticas. Pense nele como o "SQLite para analytics" — não precisa de servidor, não precisa de configuração, e roda dentro do seu processo Python.

As principais características do DuckDB:

- **Zero configuração** — não precisa instalar servidor, criar usuários ou configurar portas
- **SQL completo** — suporte a window functions, CTEs, subqueries e agregações complexas
- **Integração nativa com Python** — lê DataFrames do Pandas e [Polars](/blog/polars-alternativa-pandas-python/) diretamente
- **Leitura direta de arquivos** — CSV, Parquet, JSON e até arquivos remotos via HTTP
- **Performance absurda** — processamento colunar vetorizado, muito mais rápido que Pandas para agregações

## Instalação e Primeiros Passos

A instalação é simples com [pip](/glossario/pip/) ou [uv](/blog/uv-gerenciador-pacotes-python/):

```python
# Instalação
# pip install duckdb
# ou com uv:
# uv pip install duckdb

import duckdb

# Criar conexão in-memory
con = duckdb.connect()

# Consulta simples
resultado = con.sql("SELECT 42 AS resposta")
print(resultado.fetchone())
# (42,)
```

O DuckDB também funciona sem criar conexão explícita — você pode usar o módulo diretamente:

```python
import duckdb

# Sem conexão explícita
df = duckdb.sql("SELECT * FROM range(10) AS t(numero)").df()
print(df)
```

O método `.df()` converte o resultado diretamente para um DataFrame do Pandas, e `.pl()` converte para Polars.

## SQL Direto em Arquivos CSV e Parquet

Uma das features mais poderosas do DuckDB é consultar arquivos sem carregá-los em memória primeiro:

```python
import duckdb

# Consultar CSV diretamente
resultado = duckdb.sql("""
    SELECT
        cidade,
        COUNT(*) as total,
        AVG(salario) as salario_medio
    FROM 'dados_funcionarios.csv'
    GROUP BY cidade
    ORDER BY salario_medio DESC
    LIMIT 10
""")

print(resultado.df())
```

Com arquivos Parquet, a performance é ainda melhor porque o DuckDB aproveita o formato colunar para ler apenas as colunas necessárias:

```python
import duckdb

# Ler múltiplos arquivos Parquet com glob
resultado = duckdb.sql("""
    SELECT
        ano,
        SUM(receita) as receita_total,
        COUNT(DISTINCT cliente_id) as clientes_unicos
    FROM 'dados/vendas_*.parquet'
    WHERE ano >= 2024
    GROUP BY ano
    ORDER BY ano
""")

print(resultado.df())
```

## Integração com Pandas e Polars

O DuckDB se integra perfeitamente com o ecossistema Python de dados. Você pode rodar SQL diretamente em DataFrames que já existem na memória:

```python
import pandas as pd
import duckdb

# Criar DataFrame do Pandas
vendas = pd.DataFrame({
    "produto": ["Notebook", "Mouse", "Teclado", "Monitor", "Notebook"],
    "valor": [4500, 120, 280, 1800, 5200],
    "quantidade": [10, 150, 80, 25, 8],
    "regiao": ["Sul", "Sudeste", "Sul", "Nordeste", "Sudeste"]
})

# SQL direto no DataFrame — sem cópia de dados!
resultado = duckdb.sql("""
    SELECT
        regiao,
        SUM(valor * quantidade) as faturamento,
        COUNT(*) as num_vendas
    FROM vendas
    GROUP BY regiao
    ORDER BY faturamento DESC
""")

print(resultado.df())
```

O DuckDB referencia o DataFrame pelo nome da variável Python — não precisa importar nem registrar nada. Ele também funciona com [Polars](/blog/polars-alternativa-pandas-python/):

```python
import polars as pl
import duckdb

# DataFrame Polars
df_polars = pl.DataFrame({
    "nome": ["Ana", "Bruno", "Carla", "Diego"],
    "idade": [28, 35, 42, 31],
    "linguagem": ["Python", "Go", "Rust", "Python"]
})

# SQL direto no Polars DataFrame
resultado = duckdb.sql("""
    SELECT linguagem, AVG(idade) as idade_media
    FROM df_polars
    GROUP BY linguagem
""")

# Converter de volta para Polars
print(resultado.pl())
```

## Window Functions e Consultas Avançadas

O DuckDB suporta SQL completo, incluindo window functions que são difíceis de replicar com Pandas puro:

```python
import duckdb

# Criar tabela de exemplo
con = duckdb.connect()
con.sql("""
    CREATE TABLE vendas AS
    SELECT * FROM (VALUES
        ('2024-01', 'Eletrônicos', 45000),
        ('2024-02', 'Eletrônicos', 52000),
        ('2024-03', 'Eletrônicos', 48000),
        ('2024-01', 'Roupas', 32000),
        ('2024-02', 'Roupas', 28000),
        ('2024-03', 'Roupas', 35000)
    ) AS t(mes, categoria, receita)
""")

# Window functions: ranking e média móvel
resultado = con.sql("""
    SELECT
        mes,
        categoria,
        receita,
        RANK() OVER (PARTITION BY mes ORDER BY receita DESC) as ranking,
        AVG(receita) OVER (
            PARTITION BY categoria
            ORDER BY mes
            ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
        ) as media_movel
    FROM vendas
    ORDER BY mes, ranking
""")

print(resultado.df())
```

Isso seria muito mais verboso e lento usando `.groupby()` e `.rolling()` do Pandas.

## DuckDB vs Pandas: Quando Usar Cada Um

A pergunta que todo mundo faz: **quando trocar Pandas por DuckDB?**

| Cenário | Pandas | DuckDB |
|---------|--------|--------|
| Datasets pequenos (<100MB) | Ótimo | Funciona, mas desnecessário |
| Datasets grandes (1GB+) | Lento, consome muita RAM | Excelente, processamento colunar |
| Agregações complexas | Verboso com groupby | SQL natural e rápido |
| Window functions | Difícil e lento | SQL nativo, muito rápido |
| Manipulação célula a célula | Ideal com .apply() | Não é o forte |
| Leitura de Parquet | Carrega tudo em memória | Lê apenas colunas necessárias |
| Joins em tabelas grandes | Lento com merge() | Otimizado com hash joins |

### Benchmark prático

Para dar uma ideia concreta, aqui vai um comparativo com 10 milhões de linhas:

```python
import pandas as pd
import duckdb
import time

# Gerar dataset grande
n = 10_000_000
df = pd.DataFrame({
    "categoria": [f"cat_{i % 100}" for i in range(n)],
    "valor": range(n),
    "regiao": [f"reg_{i % 10}" for i in range(n)]
})

# Pandas
inicio = time.time()
resultado_pandas = df.groupby(["categoria", "regiao"])["valor"].agg(["sum", "mean", "count"])
tempo_pandas = time.time() - inicio

# DuckDB
inicio = time.time()
resultado_duckdb = duckdb.sql("""
    SELECT categoria, regiao, SUM(valor), AVG(valor), COUNT(*)
    FROM df
    GROUP BY categoria, regiao
""").df()
tempo_duckdb = time.time() - inicio

print(f"Pandas: {tempo_pandas:.2f}s")
print(f"DuckDB: {tempo_duckdb:.2f}s")
# Resultado típico: Pandas ~3.5s, DuckDB ~0.4s
```

Em agregações com datasets grandes, o DuckDB costuma ser **5 a 10 vezes mais rápido** que o Pandas.

## Persistência e Banco de Dados em Disco

Embora o modo in-memory seja o mais comum, o DuckDB também persiste dados em disco:

```python
import duckdb

# Criar banco persistente
con = duckdb.connect("meu_banco.duckdb")

# Criar e popular tabela
con.sql("""
    CREATE TABLE IF NOT EXISTS clientes (
        id INTEGER PRIMARY KEY,
        nome VARCHAR,
        email VARCHAR,
        criado_em TIMESTAMP DEFAULT current_timestamp
    )
""")

con.sql("""
    INSERT INTO clientes (id, nome, email) VALUES
    (1, 'Ana Silva', 'ana@email.com'),
    (2, 'Bruno Costa', 'bruno@email.com')
""")

# Os dados persistem entre sessões
con.close()

# Reabrir depois
con = duckdb.connect("meu_banco.duckdb")
print(con.sql("SELECT * FROM clientes").df())
con.close()
```

O arquivo `.duckdb` é portátil — você pode compartilhá-lo com colegas ou incluir em pipelines de dados.

## DuckDB em Projetos Reais

### ETL simples com DuckDB

```python
import duckdb

con = duckdb.connect()

# Extrair de CSV, transformar com SQL, carregar em Parquet
con.sql("""
    COPY (
        SELECT
            UPPER(nome) as nome,
            CAST(salario AS DECIMAL(10,2)) as salario,
            CASE
                WHEN salario > 10000 THEN 'senior'
                WHEN salario > 5000 THEN 'pleno'
                ELSE 'junior'
            END as nivel
        FROM 'funcionarios_raw.csv'
        WHERE salario IS NOT NULL
    ) TO 'funcionarios_limpo.parquet' (FORMAT PARQUET)
""")
```

### Análise exploratória rápida

```python
import duckdb

# Resumo estatístico instantâneo de qualquer arquivo
resumo = duckdb.sql("""
    SUMMARIZE SELECT * FROM 'dataset.parquet'
""")
print(resumo.df())
```

O comando `SUMMARIZE` gera estatísticas descritivas (min, max, média, desvio padrão, nulos) automaticamente — parecido com `df.describe()` do Pandas, mas funciona direto no arquivo.

## Quando NÃO Usar DuckDB

O DuckDB é fantástico para analytics, mas não é solução para tudo:

- **Aplicações web com múltiplos usuários** — use [PostgreSQL](/blog/python-e-postgresql/) ou [MongoDB](/blog/python-e-mongodb/)
- **Cache e filas** — use [Redis](/blog/python-e-redis/)
- **Dados simples e leves** — [SQLite](/blog/python-e-banco-de-dados-sqlite/) continua sendo suficiente
- **Streaming de dados em tempo real** — use ferramentas como Kafka ou [MQTT](/blog/python-e-mqtt-iot/)

O DuckDB é ideal para análise de dados local, ETL, exploração de datasets e qualquer cenário onde você precisa de SQL rápido sem infraestrutura.

## Conclusão

O DuckDB preenche uma lacuna importante no ecossistema Python de dados: análise rápida sem complexidade. Ele combina a simplicidade do [SQLite](/glossario/sqlalchemy/) com a potência de um banco analítico moderno, e a integração nativa com Pandas e Polars torna a adoção praticamente sem atrito.

Se você trabalha com [ciência de dados](/blog/python-para-ciencia-de-dados/) ou precisa processar datasets que não cabem confortavelmente no Pandas, o DuckDB merece um lugar no seu toolkit. A curva de aprendizado é mínima — se você sabe SQL, já sabe usar DuckDB.

> Se performance é prioridade nos seus projetos, vale conhecer também o <a href="https://rustlang.com.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust</a>, a linguagem por trás de ferramentas como Polars e Ruff que estão revolucionando o ecossistema Python.

> Para quem trabalha com análise de dados e quer explorar uma linguagem compilada com ótimo suporte a concorrência, confira o <a href="https://golang.com.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">Go</a> — muito usado em pipelines de dados e ferramentas de infraestrutura.
