# Querying your data (/use-cases/data-agents/querying-your-data)



`SQLTools` connects an agent to a database. Point it at a read-only connection and the agent can introspect the schema and run queries.

```bash
uv pip install "agno[openai,psycopg,sql]"
```

Set `OPENAI_API_KEY` in the environment before running the Python code. Replace the warehouse URLs with your own PostgreSQL connection strings and create the database roles, schemas, and grants described on this page first. The host `warehouse`, database `analytics`, and roles such as `readonly` and `dash_writer` are placeholders.

Examples using `PostgresDb` or `PgVector` also need a separate writable application database. The sample URL assumes a PostgreSQL service at `localhost:5532` with database/user/password `ai`; knowledge examples need the pgvector extension. See [PgVector setup](/knowledge/vector-stores/pgvector/overview). Keep this application's storage credentials separate from the restricted warehouse role.

```python
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.openai import OpenAIResponses
from agno.tools.sql import SQLTools
from sqlalchemy import create_engine

warehouse_url = "postgresql+psycopg://readonly@warehouse/analytics"
readonly_engine = create_engine(
    warehouse_url,
    connect_args={"options": "-c default_transaction_read_only=on"},
)

agent = Agent(
    model=OpenAIResponses(id="gpt-5.5"),
    db=PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai"),
    tools=[SQLTools(db_engine=readonly_engine)],
    instructions=(
        "Introspect the schema before writing SQL. Answer with the numbers "
        "and the exact query you ran. Never guess a column name. Pass "
        "limit=None to run_sql_query when the answer needs every row."
    ),
)

agent.print_response("How many active subscriptions are on the Pro plan?")
```

The agent's `db` and the `SQLTools` connection are separate. `db` stores the agent's sessions. `SQLTools` points at the warehouse you are answering questions about. Keep them distinct.

## Introspect before generating [#introspect-before-generating]

`SQLTools` provides `list_tables` and `describe_table` so the agent can read the current schema before generating SQL. The instruction above asks for schema introspection on each request; the model decides whether to call those tools. Fetch schema context in application code before the run when inspection must be guaranteed.

| Tool             | Use                                  |
| ---------------- | ------------------------------------ |
| `list_tables`    | Discover what exists before querying |
| `describe_table` | Get exact column names and types     |
| `run_sql_query`  | Execute the generated SQL            |

`run_sql_query(query, limit=10)` returns at most 10 rows unless the agent passes a different `limit`. Pass `limit=None` for the full result set. Otherwise a `GROUP BY` over more than 10 groups comes back truncated with no sign that rows were dropped, so tell the agent when an answer needs every row.

## Scope the connection [#scope-the-connection]

`SQLTools` executes any SQL the engine permits. It does not classify statements as read-only. This engine starts transactions with `default_transaction_read_only=on`, which blocks ordinary write statements. Because that setting is a configurable session default, use a non-owner database role with no write grants as the hard boundary. See [Safe data access](/use-cases/data-agents/safe-data-access) for the full read and write split.

## Next steps [#next-steps]

| Task                         | Guide                                                                   |
| ---------------------------- | ----------------------------------------------------------------------- |
| Ground SQL in business rules | [Grounding in context](/use-cases/data-agents/grounding-in-context)     |
| Stop repeating query errors  | [Self-correcting agents](/use-cases/data-agents/self-correcting-agents) |
| Allow controlled writes      | [Safe data access](/use-cases/data-agents/safe-data-access)             |

## Developer Resources [#developer-resources]

* [SQL tools cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/91_tools/sql_tools.py)
* [Dash: the multi-agent data team](/deploy/templates/dash/overview)
