langchainsqlpythondata-engineeringcomparison

LangChain SQLDatabaseChain vs DataSpoc Lens: Qual é Melhor para Queries de Dados?

Michael San Martim · 2026-04-16

O SQLDatabaseChain do LangChain foi uma das primeiras ferramentas que permitiram LLMs consultarem bancos de dados. O DataSpoc Lens usa uma abordagem diferente: um motor de query construído especificamente para Parquet na nuvem. Ambos permitem fazer perguntas em linguagem natural sobre dados. Eles resolvem o problema de formas muito diferentes.

Este post coloca os dois lado a lado com código real, e depois dá um veredito.

O Setup: LangChain SQLDatabaseChain

LangChain precisa de uma conexão com banco de dados, um LLM e uma chain que os conecta:

Terminal window
pip install langchain langchain-openai langchain-community sqlalchemy psycopg2-binary
from langchain_community.utilities import SQLDatabase
from langchain_openai import ChatOpenAI
from langchain.chains import create_sql_query_chain
from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
# 1. Connect to your database
db = SQLDatabase.from_uri(
"postgresql://user:password@host:5432/analytics",
include_tables=["orders", "customers", "products"], # limit scope
sample_rows_in_table_info=3, # include sample rows in schema prompt
)
# 2. Create LLM
llm = ChatOpenAI(model="gpt-4o", temperature=0)
# 3. Create the chain
query_chain = create_sql_query_chain(llm, db)
execute_tool = QuerySQLDataBaseTool(db=db)
# 4. Ask a question
sql = query_chain.invoke({"question": "What were total sales by region last quarter?"})
print(f"Generated SQL: {sql}")
result = execute_tool.invoke(sql)
print(f"Result: {result}")

Isso funciona, mas note o que você precisa: uma instância PostgreSQL rodando, credenciais no seu código, acesso de rede ao banco de dados e o driver SQLAlchemy correto instalado.

O Setup: DataSpoc Lens

O Lens conecta diretamente a arquivos Parquet no seu bucket na nuvem:

Terminal window
pip install dataspoc-lens
from dataspoc_lens import LensClient
lens = LensClient() # reads config from ~/.dataspoc/config.yaml or env vars
# List what's available
print(lens.tables())
# ['raw_orders', 'raw_customers', 'curated_sales', 'gold_revenue']
# Ask a question (natural language → SQL → execute → result)
answer = lens.ask("What were total sales by region last quarter?")
print(answer)
# Or write SQL directly
df = lens.query("""
SELECT region, SUM(amount) as total_sales
FROM curated_sales
WHERE sale_date >= '2026-01-01'
GROUP BY region
ORDER BY total_sales DESC
""")
print(df)

Sem servidor de banco de dados. Sem credenciais no código. Sem SQLAlchemy. Os dados vivem como arquivos Parquet em S3/GCS/Azure, e o Lens os lê com DuckDB.

Lado a Lado: As Mesmas 5 Tarefas

Tarefa 1: Listar Tabelas Disponíveis

# LangChain
print(db.get_usable_table_names())
# Requires active DB connection
# DataSpoc Lens
print(lens.tables())
# Reads from bucket manifest — no database needed

Tarefa 2: Explorar um Schema

# LangChain
print(db.get_table_info(table_names=["orders"]))
# Returns CREATE TABLE + sample rows (sent to LLM as context)
# DataSpoc Lens
print(lens.schema("raw_orders"))
# Returns column names and types as a dict

Tarefa 3: Query em Linguagem Natural

# LangChain
chain = create_sql_query_chain(llm, db)
sql = chain.invoke({"question": "Top 5 customers by lifetime value"})
result = execute_tool.invoke(sql)
# DataSpoc Lens
answer = lens.ask("Top 5 customers by lifetime value")

Tarefa 4: SQL Direto

# LangChain
result = db.run("SELECT customer_id, SUM(amount) FROM orders GROUP BY 1 ORDER BY 2 DESC LIMIT 5")
# DataSpoc Lens
df = lens.query("SELECT customer_id, SUM(amount) FROM raw_orders GROUP BY 1 ORDER BY 2 DESC LIMIT 5")
# Returns a pandas DataFrame, not a string

Tarefa 5: Usar com um Agente de IA

# LangChain — define as a tool
from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain.tools import Tool
tools = [
Tool(name="query_db", func=execute_tool.invoke, description="Run SQL"),
Tool(name="list_tables", func=db.get_usable_table_names, description="List tables"),
]
agent = create_openai_tools_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools)
executor.invoke({"input": "Analyze sales trends"})
# DataSpoc Lens — native MCP server
# No code needed. Just configure the MCP server:
# dataspoc-lens mcp
# Any MCP-compatible agent (Claude, Cursor, etc.) connects directly.

Matriz de Comparação

CritérioLangChain SQLDatabaseChainDataSpoc Lens
Fonte de dadosQualquer banco SQL (Postgres, MySQL, etc.)Parquet em S3/GCS/Azure
InfraestruturaBanco de dados rodando + acesso de redeApenas bucket na nuvem
CredenciaisString de conexão com user/passwordCloud IAM (sem secrets)
Motor de queryMotor do próprio bancoDuckDB (in-process)
Linguagem naturalLLM gera SQL via chainlens.ask() integrado
Integração com agentesAgents/tools LangChainServidor MCP (qualquer cliente)
Tipo de retornoStringpandas DataFrame
CacheNenhum integradolens.cache_status(), lens.cache_refresh()
Tempo de setup10-30 minutos2 minutos
CustoCompute do banco + tokens LLMApenas tokens LLM
Segurança de escritaPode executar INSERT/UPDATE/DELETESomente leitura por design

Onde LangChain Ganha

A SQL chain do LangChain é a escolha certa quando:

  1. Seus dados vivem em um banco de dados tradicional. Se está em Postgres, MySQL ou Snowflake e você não quer movê-los, LangChain conecta diretamente.

  2. Você precisa de JOINs entre múltiplos bancos. LangChain pode conectar a múltiplos bancos através de diferentes chains.

  3. Você já está no ecossistema LangChain. Se sua aplicação usa LangChain para outras coisas (recuperação de documentos, memória de chat, orquestração de ferramentas), adicionar SQLDatabaseChain é natural.

# LangChain excels at ad-hoc DB access
from langchain_community.utilities import SQLDatabase
# Connect to your production read replica
db = SQLDatabase.from_uri("postgresql://readonly:pass@replica:5432/prod")

Onde DataSpoc Lens Ganha

Lens é a escolha certa quando:

  1. Seus dados estão em um lake (Parquet em S3/GCS/Azure). Lens é construído especificamente para isso. Sem banco de dados para gerenciar.

  2. Você quer zero infraestrutura. Sem servidor de banco, sem connection pooling, sem read replicas. DuckDB roda in-process.

  3. Você precisa de acesso nativo para agentes. O servidor MCP significa que qualquer cliente MCP (Claude Code, Cursor, agentes customizados) conecta sem escrever código wrapper.

  4. Segurança importa. Cloud IAM controla o acesso. Sem credenciais de banco para gerenciar ou vazar. Somente leitura por design.

# Lens excels at data lake access
from dataspoc_lens import LensClient
lens = LensClient()
# Data comes from Parquet in your bucket — no DB needed
df = lens.query("SELECT * FROM curated_sales WHERE region = 'EMEA' LIMIT 100")

Híbrido: Use Ambos

Se você tem dados tanto em um banco quanto em um lake, pode usar ambos no mesmo agente:

import json
from openai import OpenAI
from langchain_community.utilities import SQLDatabase
from dataspoc_lens import LensClient
openai_client = OpenAI()
db = SQLDatabase.from_uri("postgresql://readonly:pass@host:5432/app")
lens = LensClient()
TOOLS = [
{
"type": "function",
"function": {
"name": "query_app_db",
"description": "Query the application database (users, sessions, settings).",
"parameters": {
"type": "object",
"properties": {"sql": {"type": "string"}},
"required": ["sql"],
},
},
},
{
"type": "function",
"function": {
"name": "query_data_lake",
"description": "Query the data lake (sales, events, analytics).",
"parameters": {
"type": "object",
"properties": {"sql": {"type": "string"}},
"required": ["sql"],
},
},
},
]
def dispatch(name, args):
if name == "query_app_db":
return db.run(args["sql"])
elif name == "query_data_lake":
df = lens.query(args["sql"])
return df.to_json(orient="records")

O Veredito

Use LangChain SQLDatabaseChain quando seus dados estão em um banco de dados tradicional e você está construindo uma aplicação LangChain.

Use DataSpoc Lens quando seus dados estão em um data lake na nuvem (arquivos Parquet), você quer zero infraestrutura, ou precisa de acesso MCP nativo para agentes.

Use ambos quando seus dados abrangem bancos de dados e lakes. Deixe o LLM decidir qual ferramenta chamar baseado na pergunta.

O verdadeiro insight: a ferramenta importa menos que a arquitetura de dados. Se seus dados já estão em Parquet em um bucket na nuvem (e deveriam estar para analytics), o Lens dá o caminho mais simples da pergunta à resposta.

Recomendados