nl2sql-api / src /nl2sql /sql_agent.py
dvwn's picture
Update main entry point for nl2sql application > app/main.py
a218c12
Raw History Blame
2.85 kB
# Path: src/nl2sql/sql_agent.py
# SQL Agent for handling NL2SQL conversion
from src.database.db_manager import get_db_connection, get_schema_context
from langchain_core.prompts import PromptTemplate
from src.nl2sql.hf_engine import get_llm
# Craft the Prompt Template to instruct LLM on its persona
SQL_PROMPT_TEMPLATE = """You are an expert SQLite developer.
Your task is to write a syntactically correct SQLite query to answer the user's question based strictly on the provided database schema.
Return ONLY the raw SQL query.
Do not include any explanations, markdown formatting, or code blocks.
Schema Context:
{schema}
User Question:
{question}
SQL Query:"""
prompt_template = PromptTemplate(
input_variables = ["schema", "question"],
template = SQL_PROMPT_TEMPLATE
)
# Clean the output
def clean_sql(raw_sql: str) -> str:
"""
Utility to strip markdown formatting if the LLM hallucinated code blocks.
Ensure the raw string can be directly executed by the SQLite cursor.
"""
cleaned = raw_sql.strip()
if cleaned.startswith("```sql"):
cleaned = cleaned[6:]
elif cleaned.startswith("```"):
cleaned = cleaned[3:]
if cleaned.endswith("```"):
cleaned = cleaned[:-3]
return cleaned.strip()
# Function to handle NL2SQL conversion
def nl2sql_agent(user_question: str) -> dict:
"""
Complete flow execution:
Get Schema context -> Generate SQL query -> Execute SQL query -> Return results
"""
# Fetch database schema context using RAG
print(f"Fetching RAG schema context for: '{user_question}'...")
schema = get_schema_context(question = user_question)
# Generate SQL query using the schema context and user question
print("Generating SQL query via LLM...")
llm = get_llm()
# LangChain Pipeline: Pipe prompt into LLM
chain = prompt_template | llm
raw_response = chain.invoke({
"schema": schema,
"question": user_question
})
# Parse & clean the generated SQL query
generated_sql = clean_sql(raw_response)
print(f"Generated SQL: \n{generated_sql}")
# Execute the generated SQL query and fetch results
connection = get_db_connection()
if not connection:
return {
"query": generated_sql,
"error": "Could not establish database connection",
"status": "failed"
}
try:
cursor = connection.cursor()
cursor.execute(generated_sql)
results = cursor.fetchall()
return {
"query": generated_sql,
"results": results,
"status": "success"
}
except Exception as e:
return {
"query": generated_sql,
"error": str(e),
"status": f"error executing SQL: {e}"
}
finally:
connection.close()