How to Work with SQL Databases
The Agents SDK includes built-in SQL database tools that let your agents explore schemas, query data, filter, sort, aggregate, join tables, and insert rows — all without writing raw SQL. The tools are designed to be safe: they support table/schema allowlists, query timeouts, and row limits.
Prerequisites
- Completed the Getting Started tutorial
- Familiar with How to Configure Agents and How to Create Agents that Use Tools
- A SQL database accessible from your agent. PostgreSQL is supported out of the box. Other databases supported by SQLAlchemy (MySQL, SQLite, Microsoft SQL Server, Oracle, etc.) also work — you just need to install the appropriate driver package.
Step 1: Install the SQL extra
The SQL tools require sqlalchemy and a database driver. Install them via the sql extra:
pip install zetaalpha.rag-agents[sql]
Step 2: Configure the database connection
Add the SQL database configuration to the agent_configuration block of your agent_setups.json. The SDK's dependency injection system automatically matches the sql_database_tools_config key to the SQLDatabaseToolsFactory parameter and hydrates the Pydantic config model. See How to Create Injectable Dependencies for details on how this works.
[
{
"agent_identifier": "my_agent",
"agent_name": "agent",
"agent_configuration": {
"sql_database_tools_config": {
"connection_string": "postgresql://user:password@host:5432/mydb",
"allowed_schemas": ["public"],
"allowed_tables": null,
"max_rows_per_query": 10000,
"query_timeout_seconds": 30
}
}
}
]
| Parameter | Description | Default |
|---|---|---|
connection_string | SQLAlchemy connection string | (required) |
allowed_schemas | Restrict access to these schemas only | null (all) |
allowed_tables | Restrict access to these tables only (format: schema.table) | null (all) |
max_rows_per_query | Maximum rows returned per read operation | 10000 |
query_timeout_seconds | Connection timeout in seconds | 30 |
For production deployments, store the connection string in an environment variable and reference it in your config rather than hardcoding credentials.
Step 3: Enable the SQL tools source
The SQLDatabaseToolsSource is automatically registered with the SDK. To make the tools available to your agent, include sql_database_tools in your tools configuration:
[
{
"agent_identifier": "my_agent",
"agent_name": "agent",
"agent_configuration": {
"sql_database_tools_config": {
"connection_string": "postgresql://user:password@host:5432/mydb"
},
"tools_configuration": {
"enabled": true,
"include_sources": ["sql_database_tools"]
}
}
}
]
If you don't set include_sources, all registered tool sources are enabled by default.
Available tools
Once enabled, the following tools are available to the LLM:
| Tool | Description |
|---|---|
sql_list_tables | List all accessible tables (optionally filtered by schema) |
sql_get_table_schema | Get column names, types, and sample values for a table |
sql_preview_data | Preview the first N rows of a table or result |
sql_read_data | Read a range of rows from a table or intermediate result |
sql_count_rows | Count rows, optionally with filters |
sql_get_row_by_pk | Retrieve a single row by primary key |
sql_select_columns | Project specific columns into a new intermediate result |
sql_get_column_values | Get distinct or filtered column values (stored for later use) |
sql_filter_table_rows | Filter rows using conditions (eq, gt, lt, in, like, etc.) |
sql_sort_table_rows | Sort rows by a column |
sql_aggregate_column | Aggregate a column (sum, mean, min, max, count) with optional group-by |
sql_join_tables | Join two tables or intermediate results |
sql_insert_row | Insert a single row into a table |
Chaining operations
Tools that produce intermediate results (filter, sort, aggregate, select, join) return a named result that can be referenced by subsequent operations. This allows the agent to build up complex queries step by step:
- Filter orders by status →
"completed_orders" - Aggregate
completed_ordersby region →"sales_by_region" - Sort
sales_by_regionby total descending →"top_regions" - Read the final result from
"top_regions"
Stored value references
sql_get_column_values can store a list of values under a named reference. These references can then be used in filter conditions with stored_value_reference instead of value, enabling cross-table lookups:
- Get premium customer IDs → stored as
"premium_ids" - Filter orders where
customer_id IN premium_ids
Example: full agent configuration
[
{
"agent_identifier": "sql_analyst",
"agent_name": "agent",
"llm_client_configuration": {
"model": "gpt-4o"
},
"agent_configuration": {
"sql_database_tools_config": {
"connection_string": "postgresql://analyst:password@db:5432/analytics",
"allowed_schemas": ["sales"],
"max_rows_per_query": 5000
},
"tools_configuration": {
"enabled": true,
"include_sources": ["sql_database_tools"]
}
}
}
]
With this configuration, the agent can explore the sales schema, answer questions about the data, and perform multi-step analysis — all driven by natural language.
Security considerations
- Always use
allowed_schemasand/orallowed_tablesto restrict what the agent can access. Without these, the agent can query any table the database user has access to. - Use a read-only database user when the agent only needs to query data. The
sql_insert_rowtool will fail gracefully if the user lacks write permissions. - Connection strings contain credentials — never commit them to source control. Use environment variables or a secrets manager.