Integrations›LangChain

LangChain

LangChain tools for Hotdata — give your chains and agents SQL execution and instant database access.

Install

pip install "hotdata-langchain[agents]"

The agents extra adds the langchain package that create_agent lives in; the library itself needs only langchain-core. Running the quickstart also needs your model provider's integration — langchain-openai for the model string below.

Authentication

Set HOTDATA_API_KEY in your environment. Optionally set HOTDATA_WORKSPACE to pin a specific workspace.

Quickstart

from hotdata_langchain import from_env, make_hotdata_tools
from langchain.agents import create_agent

client = from_env()
tools = make_hotdata_tools(client, database_id="dbid...")

agent = create_agent(
    model="openai:gpt-4o",
    tools=tools,
    system_prompt="You are a data analyst.",
)
result = agent.invoke(
    {"messages": [{"role": "user", "content": "How many orders are in the database?"}]}
)
print(result["messages"][-1].content)

Queries run against a database scope, so pass database_id= (an instant database id). from_env().list_managed_databases() shows what is available in the workspace, with the id of each.

Tools

make_hotdata_tools returns a list of StructuredTool objects ready to pass to any LangChain agent. By default it returns five tools — hotdata_describe_tables is registered unless you pass describe_tables=False — plus a search tool when you configure one with search_table/search_column:

ToolDescription
hotdata_execute_sqlRun SQL and return JSON rows
hotdata_list_managed_databasesList Hotdata instant databases, with the id of each
hotdata_create_managed_databaseCreate a database and declare tables
hotdata_load_managed_tableLoad a parquet file — local path or URL — into a table
hotdata_describe_tablesList tables, or one table's columns and types
hotdata_search_textSearch an indexed column by text relevance, fused with meaning where the table supports it (opt-in)
hotdata_search_semanticSearch an indexed column by meaning; registered instead of the above when the column carries a vector index (opt-in)
tools = make_hotdata_tools(
    client,
    max_rows=50,           # rows returned to the agent per query (default 100)
    database_id="dbid...", # scope queries to a specific database id (optional)
)

Run SQL directly

from hotdata_langchain import execute_sql_json, result_rows_for_llm
from hotdata_langchain.databases import resolve_database_by_id

# Returns a JSON string — useful for custom tool wrappers
json_str = execute_sql_json(client, "SELECT * FROM orders LIMIT 5", database_id="dbid...")

# Returns list[dict] from a QueryResult, trimmed to max_rows
database = resolve_database_by_id(client, "dbid...")
result = client.execute_sql("SELECT * FROM orders LIMIT 100", database=database)
rows = result_rows_for_llm(result, max_rows=20)

execute_sql_json takes database_id= — the same keyword as make_hotdata_tools — and accepts a database id or an already-resolved ManagedDatabase. An id costs a lookup per call; resolve once with resolve_database_by_id and pass the record to skip it. A database name is never accepted: names are display labels and are not unique. And while client.execute_sql does accept a string, that path falls back to matching a database's display label — passing the resolved database is the dependable form there.

Instant databases

from hotdata_langchain.databases import (
    create_managed_database,
    list_managed_databases_json,
    load_managed_table,
)

# Create a database and declare tables
db = create_managed_database(
    client,
    name="sales",
    schema="public",
    tables=["orders", "customers"],
)

# Load a local parquet file into a table
loaded = load_managed_table(
    client,
    database_id=db.id,
    table="orders",
    file="orders.parquet",
)
print(f"Loaded {loaded.row_count} rows → {loaded.full_name}")

# What the workspace holds — one entry per database
print(list_managed_databases_json(client))

A listing entry carries the database's id and its name — the label passed as name at creation. Address a database by its id: the name is a display string and is not unique.

See also