Docs
Back to examples
Intermediate

Plan a Catalog-Assisted Join

Inspect tables and relationships before asking an agent to execute a multi-table read.

AgentsDatabaseIntrospection

#Goal

Use the same authoritative catalog available to the agent to confirm which resources are relevant to a join.

#Search Structural Metadata

python
from daita import Agent
from daita.catalog import CatalogSearchRequest, ResourceKind
 
async with await Agent.open("warehouse") as agent:
    source = await agent.resolve_source("Analytics")
 
    search = await agent.search_catalog(
        CatalogSearchRequest(
            agent_id=agent.id,
            query="orders customers region revenue",
            source_ids=(source.id,),
            resource_kinds=(ResourceKind.TABLE,),
            limit=10,
        )
    )
 
    for hit in search.hits:
        print(hit.name, hit.resource_id, hit.match_reasons)
 
    details = await agent.inspect_catalog_resource(search.hits[0].resource_id)
    print(details.to_dict())
 
    answer = await agent.run(
        "Join orders to customers using cataloged relationships. "
        "Return net revenue by customer region for the current quarter.",
        source_id=source.id,
    )
    print(answer.final_text)

Catalog search ranks resource names, field names, and relationship neighbors. It does not scan business rows.

#Inspect a Candidate Resource

The example inspects the first search hit through inspect_catalog_resource(). For SQLite and PostgreSQL, discovered foreign keys include related resources and field pairs. During a run, the model can use catalog_traverse to follow those relationships before composing SQL.

#Ask for the Joined Result

The final run() asks for the joined result. The SQL tool still validates every referenced table and column against the selected source's current catalog. Catalog traversal helps planning; it does not bypass query validation.

#Refresh When Structure Changes

If a migration changes a table or relationship:

Call await agent.refresh_source(source.id) while the agent is open.

The previous snapshot remains current if discovery fails. Queries against a detected stale live revision fail safely until a successful refresh commits the new structure.