Why Python Developers Are Frustrated with SQLAlchemy (and What to Use Instead)
Problem
SQLAlchemy is the de facto Python ORM, but many developers feel something is off with it. The r/Python thread “Are we happy with SQLAlchemy?” captures this sentiment well — even the OP, who is building a sqlc-equivalent for Python, said “SQLAlchemy is the best option we have in the Python ecosystem, but it still sucks compared to ORMs in other ecosystems.”
I’ve had this feeling too. Let me dig into what specifically frustrates developers and what alternatives actually exist.
The Three Frustrations
Reading through the Reddit thread, three pain points keep surfacing.
1. Complexity Overhead
SQLAlchemy has a two-tier architecture: Core and ORM. Newcomers import sqlalchemy.orm by default, struggle with session management and the “unit of work” pattern, and never realize Core exists as a simpler alternative.
One commenter said: “It’s so much more complicated than what I’ve used in other languages, like Entity Framework.”
2. Barely an Abstraction
Some developers feel SQLAlchemy is more like a thin dialect-normalization layer than a real ORM. It maps closely to SQL concepts but doesn’t hide SQL details the way Django ORM does.
The most positive review in the thread comes with a caveat: SQLAlchemy is “the best ORM I’ve used” — with the key reason being that Core lets you avoid the ORM layer entirely.
3. Dynamic Typing Issues
Python’s lack of compile-time type safety means ORM errors surface at runtime. In Go with sqlc, you get compile-time SQL validation. In Java with Hibernate, you get IDE support. In Python, a typo in a column name only shows up when you run the query.
What to Use Instead
Raw SQL + Connection Pool
The “just write raw queries” camp has multiple proponents in the thread. If you already know SQL, why add another layer?
import psycopg2
conn = psycopg2.connect("dbname=test user=postgres")with conn.cursor() as cur: cur.execute("SELECT id, title, pub_date FROM blogs WHERE pub_date > %s", ("2026-01-01",)) rows = cur.fetchall()This is simple, transparent, and fast. The downside: no query builder, no object tracking, and you manually handle result mapping.
Pydantic + Raw SQL
A middle ground: define models as Pydantic schemas, write raw SQL, and validate results.
from pydantic import BaseModelimport psycopg2
class Blog(BaseModel): id: int title: str pub_date: str
with conn.cursor() as cur: cur.execute("SELECT id, title, pub_date FROM blogs") blogs = [Blog(**row) for row in cur.fetchall()]This gives you type validation at the boundary without ORM overhead.
Django ORM
If you’re already in the Django ecosystem, its ORM is widely considered more ergonomic. The tradeoff is framework coupling.
Code-Generated SQL (Emerging)
The most interesting direction from the thread: code-generated SQL tools inspired by Go’s sqlc. The OP is building one using sqlglot that generates type-safe Python from SQL files, with support for dynamic filters and sorting.
-- query.sql-- name: get_blogs_by_date :manySELECT * FROM blogs WHERE pub_date >= :min_date ORDER BY pub_date DESC;
# Generated Python (idea)# blogs = get_blogs_by_date(engine, min_date="2026-01-01")This approach combines the safety of ORMs with the transparency of raw SQL. It’s still emerging in the Python ecosystem, but it’s worth watching.
A Decision Framework
Here’s how I think about the choice:
Are you using Django? → Django ORMDo you need SQL control? → SQLAlchemy CoreDo you hate abstractions? → Raw SQLWant type safety? → Watch for code-gen tools
For most projects, SQLAlchemy (especially Core mode) is still the most balanced choice. It gives you enough abstraction to be productive without hiding what SQL is actually being executed.
Summary
In this post, I explored why Python developers get frustrated with SQLAlchemy — complexity overhead, thin abstraction, and dynamic typing issues — and reviewed alternatives including raw SQL, Django ORM, and emerging code-generated SQL tools. The key point is that SQLAlchemy is still the most balanced choice for most projects, but knowing your alternatives helps you make smarter decisions.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 r/Python Discussion: Are we happy with SQLAlchemy?
- 👨💻 SQLAlchemy Official Documentation
- 👨💻 Django ORM Official Documentation
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments