I’m working with a LangChain agent that uses SQLDatabaseToolkit to query a PostgreSQL database. My database has two related tables:
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
dept_name VARCHAR(60) UNIQUE NOT NULL,
manager VARCHAR(60) NOT NULL
);
CREATE TABLE employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(60) NOT NULL,
salary INT,
job_title VARCHAR(25),
dept_id INT REFERENCES departments(dept_id) ON DELETE CASCADE
);
Here’s my agent setup:
template = PromptTemplate.from_template(
"""
You are an AI assistant. Use available tools to query the database.
When asked for employees from a specific department, query the 'employees' table
and join with 'departments' table using dept_id, then filter by dept_name.
Sample query: "Show me all employees from Marketing" → Run:
SELECT e.emp_name
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
WHERE d.dept_name = 'Marketing';
Finish with: "The Marketing department employees are ...".
{agent_scratchpad}
"""
)
connection = SQLDatabase.from_uri("postgresql+psycopg2://user:pass@localhost:5433/company")
sql_toolkit = SQLDatabaseToolkit(db=connection, llm=model)
available_tools = sql_toolkit.get_tools()
executor = initialize_agent(
tools=available_tools,
llm=model,
agent_type="tool-calling",
verbose=True
)
When I ask about Marketing employees, the agent generates wrong SQL like SELECT employees FROM departments WHERE name = 'Marketing' instead of properly joining tables. Why doesn’t SQLDatabaseToolkit handle relationships between tables automatically? What’s the best way to fix this behavior?
yea, sqlDatabaseToolkit has issues with joins. maybe try rephrasing your prompts or using create_sql_agent? it’s way better at managing relationships between tables.
the sql agent really struggles with foreign keys. set verbose=false and add a custom_suffix to your prompt that spells out the table structures explicitly. fixed the same join problems i was having with my CRM tables.
Been dealing with SQL agent headaches for years. All this prompt engineering and schema tweaking? Just patching a broken system.
I ditched LangChain’s limitations and moved my database workflows to Latenode. You build visual flows that handle complex joins - no SQL writing, no wrestling with LLM interpretations.
Here’s my setup: flow connects to PostgreSQL, I define table relationships once in the visual builder, then create endpoints for different queries. Someone asks for “Marketing employees”? It automatically joins employees and departments tables because I mapped that relationship visually.
No prompt debugging. No broken SQL generation. Drag and drop database nodes, define joins visually, works every time.
Best part? Expose these flows as APIs or webhooks. Your frontend calls a clean endpoint instead of hoping an AI agent generates correct SQL.
Check it out: https://latenode.com
I’ve hit this same problem tons of times. SQLDatabaseToolkit works fine - the real issue is the LLM doesn’t get your database structure.
Here’s what actually worked: I put table schemas right in the prompt. Don’t trust the toolkit to figure out relationships. I stick the actual CREATE TABLE statements in my template so the LLM sees exactly what columns exist and how they connect.
Use few_shot_examples when creating the agent. Give it 3-4 correct JOIN examples for your tables. LLMs learn way better from examples than explanations.
Also check your context window. If you’ve got a massive database, the toolkit dumps too much schema info and buries your instructions. Use include_tables to show only what matters.
I switched to this after days of prompt tweaking and the JOIN problems disappeared instantly.
Had the same problem with SQLDatabaseToolkit on a multi-table PostgreSQL setup. The toolkit doesn’t automatically pick up foreign key relationships, even when they’re defined properly in your schema. Here’s what worked for me: add the table relationships directly in your prompt template and use the include_tables parameter to limit which tables the agent can access. I’d also throw in some sample JOIN queries in your prompt - the LLM picks up on patterns way better with concrete examples. Quick debug tip: print connection.get_table_info() to check if the toolkit’s actually reading your foreign key constraints correctly.
The SQLDatabaseToolkit struggles with implicit relationships and tends to misinterpret foreign key constraints when generating queries. To circumvent this issue, I’ve found that explicitly defining the schema context in the agent’s prompt is beneficial. Instead of relying on the toolkit to automatically handle joins, you should clearly describe the relationships in your template, such as stating that ‘departments and employees connect through the dept_id field.’ Additionally, assess the capabilities of your LLM, as some perform significantly better with complex queries than others. In my experience, switching from initialize_agent to create_sql_agent while including a custom system message that details your specific database schema alongside common query patterns has yielded much better results.