Built by backendbrilliance Β· EPAM
An interactive web application that converts natural language into SQL queries using your own database schema (ERD). Upload a YAML ERD, describe what you want in plain English, and get production-ready PostgreSQL instantly.
| Handle | aagrahari |
| Organization | EPAM |
| Website | dynamicallyblunttech.com |
- Quick Start (Docker Hub)
- Publishing to Docker Hub
- Features
- ERD Format
- Installation
- LLM Provider Setup
- Using the UI
- API Reference
- Environment Variables
No Python. No code. Just Docker.
docker run -d -p 5000:5000 --name sql-gen aagrahari/sql-generator:latestThen open http://localhost:5000 in your browser.
With your API key pre-configured:
docker run -d -p 5000:5000 \
-e OPENAI_API_KEY=sk-... \
-e FLASK_SECRET_KEY=your-random-secret \
--name sql-gen \
aagrahari/sql-generator:latestPersist uploaded ERDs across restarts:
docker run -d -p 5000:5000 \
-e OPENAI_API_KEY=sk-... \
-e FLASK_SECRET_KEY=your-random-secret \
-v ./uploads:/app/uploads \
--name sql-gen \
aagrahari/sql-generator:latestUseful commands:
docker stop sql-gen # Stop the container
docker start sql-gen # Restart it (data preserved)
docker logs sql-gen # View logs
docker rm -f sql-gen # Remove container
docker pull aagrahari/sql-generator:latest # Get latest versionFollow these steps to build and push an updated image.
Prerequisites: Docker Desktop + a Docker Hub account.
# 1. Log in
docker login
# 2. Build with your Docker Hub username as prefix
docker build -t aagrahari/sql-generator:latest .
# 3. (Optional) Tag a versioned release
docker tag aagrahari/sql-generator:latest aagrahari/sql-generator:1.0
# 4. Push to Docker Hub
docker push aagrahari/sql-generator:latest
docker push aagrahari/sql-generator:1.0Image is then publicly available at:
https://hub.docker.com/r/aagrahari/sql-generator
To publish an update:
docker build -t aagrahari/sql-generator:latest .
docker push aagrahari/sql-generator:latest- π Upload your own ERD β drag-and-drop YAML schema upload
- π¬ Natural language β SQL β describe what you want, get PostgreSQL back
- π Three LLM providers β OpenAI, GitHub Models (free tier), or local Ollama
- ποΈ Schema Explorer β browse tables and columns in the sidebar
- π Query History β last 50 queries saved in the browser
- π₯ Copy / Download β one-click copy or
.sqlfile download - π³ Docker-ready β single command to run anywhere
Upload a YAML file with the following structure:
tables:
users:
columns:
id:
type: bigserial
notNull: true
email:
type: varchar(255)
notNull: true
created_at:
type: timestamptz
notNull: true
default: now()
constraints:
pk_users:
type: PRIMARY KEY
columnNames: [id]
uq_users_email:
type: UNIQUE
columnNames: [email]
orders:
columns:
id:
type: bigserial
notNull: true
user_id:
type: bigint
notNull: true
total:
type: numeric(10,2)
constraints:
pk_orders:
type: PRIMARY KEY
columnNames: [id]
fk_orders_user:
type: FOREIGN KEY
columnNames: [user_id]
targetTableName: users
targetColumnNames: [id]Supported constraint types: PRIMARY KEY, FOREIGN KEY, UNIQUE, INDEX
Requirements: Python 3.10+
# 1. Clone / copy the project folder
cd SQLGenerator
# 2. Create a virtual environment (recommended)
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS / Linux
# 3. Install dependencies
pip install -r requirements.txt
# 4. (Optional) Configure API keys
cp .env.example .env
# Edit .env and add your OPENAI_API_KEY or GITHUB_TOKEN
# 5. Run
python app.pyOpen http://localhost:5000 in your browser.
Requirements: Docker Desktop (or Docker Engine on Linux)
# Build the image
docker build -t sql-generator .
# Run (no API key pre-configured β enter in UI settings)
docker run -p 5001:5001 sql-generator
# Run with API keys pre-configured
docker run -p 5001:5001 \
-e OPENAI_API_KEY=sk-... \
-e FLASK_SECRET_KEY=my-random-secret \
sql-generator
# Persist uploaded ERDs across container restarts
docker run -p 5001:5001 \
-v $(pwd)/uploads:/app/uploads \
-e OPENAI_API_KEY=sk-... \
sql-generatorOpen http://localhost:5001 in your browser.
# Copy and edit environment variables (optional)
cp .env.example .env
# Add OPENAI_API_KEY, GITHUB_TOKEN, FLASK_SECRET_KEY to .env
# Start
docker-compose up --build
# Stop
docker-compose downThe uploads/ folder is mounted as a volume, so uploaded ERDs survive restarts.
Configure the provider by clicking "LLM Provider" in the top-right of the UI. Three providers are supported:
| Field | Value |
|---|---|
| API Key | Your OpenAI key (sk-...) from platform.openai.com |
| Model | gpt-4o-mini (default), gpt-4o, gpt-4-turbo, etc. |
| Field | Value |
|---|---|
| Token | A GitHub Personal Access Token (PAT) with models:read scope β create one here |
| Model | gpt-4o-mini, gpt-4o, Phi-4, Meta-Llama-3.1-70B-Instruct, etc. |
GitHub Models is free for personal use with generous rate limits. No credit card required.
| Field | Value |
|---|---|
| Base URL | http://localhost:11434/v1 (default) |
| Model | Any model you have pulled, e.g. llama3.2, mistral, codellama |
# Install Ollama: https://ollama.com
ollama pull llama3.2
ollama serve-
Upload ERD β Click "Upload ERD" in the sidebar (or drag-and-drop a
.yaml/.ymlfile onto the upload modal). The sidebar will populate with your tables. -
Browse Schema β Click any table in the sidebar to see its columns, types, primary keys, and foreign key relationships.
-
Write a Prompt β Type a plain-English description in the prompt box, for example:
- "Show all orders placed in the last 30 days with customer email"
- "Count total revenue per product category, ordered by highest first"
- "Find users who haven't placed any orders"
-
Generate SQL β Click "Generate SQL" (or press
Ctrl+Enter). The SQL appears in the editor with syntax highlighting. -
Use the Result β Copy to clipboard or download as a
.sqlfile using the buttons above the editor. -
History β The last 50 generated queries are saved in your browser. Click the clock icon in the toolbar to browse and reload previous queries.
-
Remove ERD β Click the Γ next to the ERD name in the sidebar to remove the current schema and upload a different one.
All endpoints return JSON. Errors follow {"error": "<message>"} with an appropriate HTTP status code.
Serves the web application UI.
Returns the active ERD for the current session.
Response (ERD loaded)
{
"tables": [
{
"name": "users",
"columnCount": 4,
"columns": [
{
"name": "id",
"type": "bigserial",
"notNull": true,
"isPrimaryKey": true,
"isForeignKey": false,
"foreignKey": null
}
]
}
],
"total": 1,
"erd_name": "my-schema.yaml",
"is_custom": true
}Response (no ERD uploaded)
{
"tables": [],
"total": 0,
"erd_name": null,
"is_custom": false
}Uploads a YAML ERD file and associates it with the current session.
Request β multipart/form-data
| Field | Type | Description |
|---|---|---|
file |
File | .yaml or .yml ERD file (max 5 MB) |
Response (success)
{
"success": true,
"erd_name": "my-schema.yaml",
"tables": [ ... ],
"total": 12,
"is_custom": true
}Error responses
| HTTP | Reason |
|---|---|
400 |
No file provided |
400 |
File is not .yaml / .yml |
400 |
File exceeds 5 MB |
400 |
Invalid YAML syntax |
400 |
Missing top-level tables key |
400 |
ERD contains no tables |
Removes the uploaded ERD from the current session.
Response
{
"tables": [],
"total": 0,
"erd_name": null,
"is_custom": false
}Generates a SQL query from a natural language prompt using the configured LLM.
Request body β application/json
| Field | Type | Required | Description |
|---|---|---|---|
prompt |
string | β | Natural language description of the query |
provider |
string | openai (default), github, or ollama |
|
model |
string | Model name (default: gpt-4o-mini) |
|
api_key |
string | API key / PAT. Falls back to environment variable if omitted | |
base_url |
string | Custom base URL (useful for self-hosted or Ollama) |
Example request
{
"prompt": "Show all customers with more than 5 orders in the last 90 days",
"provider": "openai",
"model": "gpt-4o-mini",
"api_key": "sk-..."
}Response (success)
{
"sql": "SELECT c.id, c.email, COUNT(o.id) AS order_count\nFROM customers c\nJOIN orders o ON o.customer_id = c.id\nWHERE o.created_at >= NOW() - INTERVAL '90 days'\nGROUP BY c.id, c.email\nHAVING COUNT(o.id) > 5\nORDER BY order_count DESC;",
"model": "gpt-4o-mini",
"provider": "openai",
"prompt_tokens": 812,
"completion_tokens": 74
}Error responses
| HTTP | Reason |
|---|---|
400 |
Prompt is empty |
400 |
No ERD uploaded |
400 |
API key / token missing |
500 |
LLM API error (invalid key, quota exceeded, connection refused) |
| Variable | Default | Description |
|---|---|---|
OPENAI_API_KEY |
(empty) | Pre-configure OpenAI key (can also be entered in UI) |
GITHUB_TOKEN |
(empty) | Pre-configure GitHub PAT for GitHub Models |
FLASK_SECRET_KEY |
dev-secret-change-in-production |
Change this in production. Used to sign session cookies |
FLASK_DEBUG |
true (local) / false (Docker) |
Enable Flask debug mode |
Security note: Always set a strong, random
FLASK_SECRET_KEYin production. You can generate one with:python -c "import secrets; print(secrets.token_hex(32))"