LangChain SQLDatabaseChain vs DataSpoc Lens: ¿Cuál Es Mejor para Consultas de Datos?
SQLDatabaseChain de LangChain fue una de las primeras herramientas que permitieron a los LLMs consultar bases de datos. DataSpoc Lens toma un enfoque diferente: un motor de consultas diseñado específicamente para Parquet en la nube. Ambos te permiten hacer preguntas en lenguaje natural sobre datos. Resuelven el problema de manera muy diferente.
Este artículo los pone lado a lado con código real, y luego te da un veredicto.
La Configuración: LangChain SQLDatabaseChain
LangChain necesita una conexión a base de datos, un LLM y una cadena que los une:
pip install langchain langchain-openai langchain-community sqlalchemy psycopg2-binaryfrom langchain_community.utilities import SQLDatabasefrom langchain_openai import ChatOpenAIfrom langchain.chains import create_sql_query_chainfrom langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
# 1. Connect to your databasedb = 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 LLMllm = ChatOpenAI(model="gpt-4o", temperature=0)
# 3. Create the chainquery_chain = create_sql_query_chain(llm, db)execute_tool = QuerySQLDataBaseTool(db=db)
# 4. Ask a questionsql = 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}")Esto funcióna, pero nota lo que necesitas: una instancia de PostgreSQL corriendo, credenciales en tu código, acceso de red a la base de datos y el driver SQLAlchemy correcto instalado.
La Configuración: DataSpoc Lens
Lens se conecta directamente a archivos Parquet en tu bucket cloud:
pip install dataspoc-lensfrom dataspoc_lens import LensClient
lens = LensClient() # reads config from ~/.dataspoc/config.yaml or env vars
# List what's availableprint(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 directlydf = 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)Sin servidor de base de datos. Sin credenciales en código. Sin SQLAlchemy. Los datos viven cómo archivos Parquet en S3/GCS/Azure, y Lens los lee con DuckDB.
Lado a Lado: Las Mismas 5 Tareas
Tarea 1: Listar Tablas Disponibles
# LangChainprint(db.get_usable_table_names())# Requires active DB connection
# DataSpoc Lensprint(lens.tables())# Reads from bucket manifest — no database neededTarea 2: Explorar un Schema
# LangChainprint(db.get_table_info(table_names=["orders"]))# Returns CREATE TABLE + sample rows (sent to LLM as context)
# DataSpoc Lensprint(lens.schema("raw_orders"))# Returns column names and types as a dictTarea 3: Consulta en Lenguaje Natural
# LangChainchain = create_sql_query_chain(llm, db)sql = chain.invoke({"question": "Top 5 customers by lifetime value"})result = execute_tool.invoke(sql)
# DataSpoc Lensanswer = lens.ask("Top 5 customers by lifetime value")Tarea 4: SQL Directo
# LangChainresult = db.run("SELECT customer_id, SUM(amount) FROM orders GROUP BY 1 ORDER BY 2 DESC LIMIT 5")
# DataSpoc Lensdf = 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 stringTarea 5: Usar con un Agente de IA
# LangChain — define as a toolfrom langchain.agents import create_openai_tools_agent, AgentExecutorfrom 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 Comparación
| Criterio | LangChain SQLDatabaseChain | DataSpoc Lens |
|---|---|---|
| Fuente de datos | Cualquier base SQL (Postgres, MySQL, etc.) | Parquet en S3/GCS/Azure |
| Infraestructura | Base de datos corriendo + acceso de red | Solo bucket cloud |
| Credenciales | Connection string con usuario/contraseña | IAM en la nube (sin secretos) |
| Motor de consultas | Motor propio de la base de datos | DuckDB (en proceso) |
| Lenguaje natural | LLM genera SQL vía chain | lens.ask() integrado |
| Integración con agentes | Agentes/herramientas de LangChain | Servidor MCP (cualquier cliente) |
| Tipo de retorno | String | pandas DataFrame |
| Cache | Ninguno integrado | lens.cache_status(), lens.cache_refresh() |
| Tiempo de configuración | 10-30 minutos | 2 minutos |
| Costo | Cómputo de BD + tokens LLM | Solo tokens LLM |
| Seguridad de escritura | Puede ejecutar INSERT/UPDATE/DELETE | Solo lectura por diseño |
Dónde Gana LangChain
La cadena SQL de LangChain es la elección correcta cuando:
-
Tus datos viven en una base de datos tradicional. Si están en Postgres, MySQL o Snowflake y no quieres moverlos, LangChain se conecta directamente.
-
Necesitas joins entre múltiples bases de datos. LangChain puede conectarse a múltiples bases de datos a través de diferentes cadenas.
-
Ya estás en el ecosistema LangChain. Si tu app usa LangChain para otras cosas (recuperación de documentos, memoria de chat, orquestación de herramientas), agregar SQLDatabaseChain es natural.
# LangChain excels at ad-hoc DB accessfrom langchain_community.utilities import SQLDatabase
# Connect to your production read replicadb = SQLDatabase.from_uri("postgresql://readonly:pass@replica:5432/prod")Dónde Gana DataSpoc Lens
Lens es la elección correcta cuando:
-
Tus datos están en un lake (Parquet en S3/GCS/Azure). Lens está diseñado específicamente para esto. Sin base de datos que gestionar.
-
Quieres cero infraestructura. Sin servidor de base de datos, sin connection pooling, sin réplicas de lectura. DuckDB se ejecuta en proceso.
-
Necesitas acceso nativo para agentes. El servidor MCP significa que cualquier cliente MCP (Claude Code, Cursor, agentes personalizados) se conecta sin escribir código envolvente.
-
La seguridad importa. IAM en la nube controla el acceso. Sin credenciales de base de datos que gestionar o filtrar. Solo lectura por diseño.
# Lens excels at data lake accessfrom dataspoc_lens import LensClient
lens = LensClient()# Data comes from Parquet in your bucket — no DB neededdf = lens.query("SELECT * FROM curated_sales WHERE region = 'EMEA' LIMIT 100")Híbrido: Usa Ambos
Si tienes datos tanto en una base de datos cómo en un lake, puedes usar ambos en el mismo agente:
import jsonfrom openai import OpenAIfrom langchain_community.utilities import SQLDatabasefrom 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")El Veredicto
Usa LangChain SQLDatabaseChain cuando tus datos están en una base de datos tradicional y estás construyendo una aplicación con LangChain.
Usa DataSpoc Lens cuando tus datos están en un data lake cloud (archivos Parquet), quieres cero infraestructura, o necesitas acceso nativo MCP para agentes.
Usa ambos cuando tus datos abarcan bases de datos y lakes. Deja que el LLM decida qué herramienta llamar según la pregunta.
El insight real: la herramienta importa menos que la arquitectura de datos. Si tus datos ya están en Parquet en un bucket cloud (y deberían estarlo para analytics), Lens te da el camino más simple de la pregunta a la respuesta.