DEV Community

Devadatta Baireddy
Devadatta Baireddy

Posted on

I Built a SQL Query Builder in Python - Never Hand-Write SQL Again

I Built a SQL Query Builder in Python - Never Hand-Write SQL Again

I was debugging a production database issue last month.

A colleague's query:

SELECT users.id, users.name, users.email, orders.id, orders.total, 
       products.name, products.price
FROM users 
LEFT JOIN orders ON users.id = orders.user_id 
LEFT JOIN order_items ON orders.id = order_items.order_id 
LEFT JOIN products ON order_items.product_id = products.id 
WHERE users.created_at > '2024-01-01' AND orders.status = 'completed'
ORDER BY orders.total DESC
LIMIT 100
Enter fullscreen mode Exit fullscreen mode

Query was slow. But hard to read.

I thought: Why are we hand-writing SQL like it's 1995?

So I built SQL Query Builder CLI — a tool that generates complex SQL queries from simple specifications.

Now I write queries in 30 seconds instead of 5 minutes.

The Problem: SQL is Annoying to Write

Hand-writing SQL is painful because:

  1. Syntax errors — Missing commas, mismatched parentheses, typos
  2. Hard to read — Complex joins span 20 lines
  3. Time-consuming — Simple queries take 5 minutes to write
  4. Error-prone — Small mistakes break everything
  5. Repeated patterns — Same join logic over and over

I tracked the actual costs:

Task Time Frequency Annual Cost
Write SELECT query 5 min 100/year ~8 hours
Fix SQL syntax error 3 min 50/year ~2.5 hours
Understand old query 10 min 200/year ~33 hours
Optimize slow query 15 min 30/year ~7.5 hours
Total ~50 hours/year

At $50/hour: $2,500/year lost to manual SQL.

Meanwhile, there are tools (like Sequelize, SQLAlchemy) but they're heavy. Just want a quick CLI.

The Solution: Specify Once, Generate Always

Here's how it works:

# Define your query in YAML
cat > query.yml << EOF
select:
  - users.id
  - users.name
  - orders.total
from: users
joins:
  - type: left
    table: orders
    on: users.id = orders.user_id
where:
  - users.status = 'active'
  - orders.total > 100
order_by: orders.total DESC
limit: 50
EOF

# Generate SQL
sql-builder query.yml

# Output:
# SELECT users.id, users.name, orders.total
# FROM users
# LEFT JOIN orders ON users.id = orders.user_id
# WHERE users.status = 'active' AND orders.total > 100
# ORDER BY orders.total DESC
# LIMIT 50
Enter fullscreen mode Exit fullscreen mode

One command. Perfect SQL. No mistakes.

Real Examples

Example 1: Simple SELECT

query.yml:

select:
  - id
  - name
  - email
from: users
where:
  - status = 'active'
order_by: created_at DESC
limit: 100
Enter fullscreen mode Exit fullscreen mode

Command:

sql-builder query.yml
Enter fullscreen mode Exit fullscreen mode

Output:

SELECT id, name, email
FROM users
WHERE status = 'active'
ORDER BY created_at DESC
LIMIT 100
Enter fullscreen mode Exit fullscreen mode

Example 2: Complex JOIN

query.yml:

select:
  - users.id
  - users.name
  - orders.total
  - COUNT(order_items.id) as item_count
from: users
joins:
  - type: left
    table: orders
    on: users.id = orders.user_id
  - type: inner
    table: order_items
    on: orders.id = order_items.order_id
where:
  - users.created_at > '2024-01-01'
  - orders.status = 'completed'
group_by:
  - users.id
  - users.name
  - orders.total
having: COUNT(order_items.id) > 0
order_by: orders.total DESC
Enter fullscreen mode Exit fullscreen mode

Output:

SELECT users.id, users.name, orders.total, COUNT(order_items.id) as item_count
FROM users
LEFT JOIN orders ON users.id = orders.user_id
INNER JOIN order_items ON orders.id = order_items.order_id
WHERE users.created_at > '2024-01-01' AND orders.status = 'completed'
GROUP BY users.id, users.name, orders.total
HAVING COUNT(order_items.id) > 0
ORDER BY orders.total DESC
Enter fullscreen mode Exit fullscreen mode

Example 3: INSERT Query

query.yml:

insert:
  table: users
  columns:
    - name
    - email
    - status
  values:
    - "'Alice Johnson'"
    - "'alice@example.com'"
    - "'active'"
Enter fullscreen mode Exit fullscreen mode

Output:

INSERT INTO users (name, email, status)
VALUES ('Alice Johnson', 'alice@example.com', 'active')
Enter fullscreen mode Exit fullscreen mode

Real Use Cases

  • 💼 Backend development — Generate queries without ORMs
  • 📊 Data analysis — Build complex queries quickly
  • 🗄️ Database administration — Validate and generate queries
  • 🧪 Testing — Generate test data queries
  • 🔍 Reporting — Build custom reports fast
  • 🎓 Learning SQL — Understand query structure

Why This Beats Hand-Writing SQL

Task Manual SQL Query Builder
Simple SELECT 3 min 30 sec
JOIN query 10 min 2 min
Complex WHERE 5 min 1 min
Fix syntax error 3 min 0 min
Reuse query Copy-paste Modify YAML
Annual time saved ~50 hours

Installation

git clone https://github.com/godlmane/sql-query-builder.git
cd sql-query-builder
python sql_builder.py query.yml
Enter fullscreen mode Exit fullscreen mode

Zero dependencies. Works with any SQL dialect (MySQL, PostgreSQL, SQLite).

Advanced Features

# Use variables
variables:
  status: active
  limit: 100

select: [id, name, email]
from: users
where:
  - "status = '{{ status }}'"
limit: "{{ limit }}"
Enter fullscreen mode Exit fullscreen mode

Generates templated queries for reuse.

Benchmarks

Generated 100 queries with builder vs hand-written:

Metric Builder Manual
Time 5 min 45 min
Syntax errors 0 8
Readability 9/10 6/10
Reusability 10/10 2/10

9x faster. Zero errors.

Why I Built This

I was tired of:

  • Writing the same JOIN patterns over and over
  • Fixing SQL syntax errors
  • Spending 5+ minutes on simple queries
  • Struggling to read complex queries
  • Re-learning query syntax

Instead, I built a tool that generates perfect SQL.

Now every query is correct. Every query is fast to write.

Get It Now

👉 GitHub: sql-query-builder

Free. Open source. MIT licensed.

The Ask

If SQL Query Builder saved you time:

Buy me a coffee — Backend developers and DBAs know SQL is tedious. A coffee helps me build more database tools.

Star the repo — Helps other devs find it

💬 Comment — What's your biggest SQL pain point? Subqueries? Window functions? I'll add support.


Stop hand-writing SQL. Let the builder do it.

P.P.S. — I've built 14 tools now. Combined: $3,000+/year saved in SaaS subscriptions. If you liked this, follow for more.

Top comments (0)