Databases

SQLAlchemy Order By Desc: How to Sort Descending

Fix NameError in SQLAlchemy order_by() for descending sort. Use desc() import or column.desc() to ORDER BY amount DESC with joins and filters. Complete examples for sql alchemy queries.

1 answer 1 view

SQLAlchemy: How to ORDER BY DESCENDING using order_by()?

I have this working query that sorts results in ascending order by model.Entry.amount:

python
query = (model.Session.query(model.Entry)
 .join(model.ClassificationItem)
 .join(model.EnumerationValue)
 .filter_by(id=c.row.id)
 .order_by(model.Entry.amount))

Attempting .order_by(desc(model.Entry.amount)) raises NameError: global name 'desc' is not defined.

What is the correct syntax to sort in descending order (DESC) in SQLAlchemy?

To sort results in descending order with SQLAlchemy’s order_by(), import desc from sqlalchemy and use .order_by(desc(model.Entry.amount)), or skip the import entirely by calling .order_by(model.Entry.amount.desc()) on the column itself. Both approaches generate the SQL ORDER BY amount DESC and sidestep that pesky NameError: global name 'desc' is not defined. Your full query just swaps the last line—no other changes needed.


Contents


Why Descending Order Matters in SQLAlchemy Queries

Ever built a query that works fine ascending but flips upside down when you need the biggest values first—like top sales amounts or latest timestamps? That’s where SQLAlchemy order by desc shines. In your case, model.Entry.amount probably tracks something like transaction values, and ascending gives you the smallest first. Flip to descending, and bam—highest amounts lead the pack.

SQLAlchemy’s ORM abstracts raw SQL, but under the hood, .order_by() builds ORDER BY clauses. Default is ascending (think ASC), but descending needs explicit signaling via desc(). The official SQLAlchemy docs describe desc() as the key for “Produce a descending ORDER BY clause element.” Without it, you’re stuck with natural order.

Why bother? Queries aren’t just pulls—they shape data stories. A dashboard showing top earners? Descending. Chronological logs? Ascending. Get this right, and your app feels snappier, more intuitive.


Fixing the NameError: Import desc or Use Column.desc()

That NameError screams “desc ain’t global!” because desc lives in SQLAlchemy’s namespace, not Python’s builtins. Quick fixes:

  1. Import it upfront: from sqlalchemy import desc. Clean, reusable across files.
  2. No import needed: Chain .desc() directly on your column. Lazy but effective.

Both crank out identical SQL. A classic Stack Overflow answer nails this: import solves the error, column method dodges it altogether. Pick based on your style—imports for big projects, inline for one-offs.

But wait, does it work with joins? Absolutely. Your query’s .join(model.ClassificationItem).join(model.EnumerationValue) stays untouched; sorting applies post-join.


Method 1: Using the desc() Helper Function

Straightforward if you’re already importing SQLAlchemy bits. Add one line at the top:

python
from sqlalchemy import desc # That's it

query = (model.Session.query(model.Entry)
 .join(model.ClassificationItem)
 .join(model.EnumerationValue)
 .filter_by(id=c.row.id)
 .order_by(desc(model.Entry.amount))) # DESC magic

Results? Highest amount first. A detailed blog post mirrors this exactly, confirming it spits ORDER BY entry.amount DESC.

Pro: Readable in complex chains. Con: One more import. Scales great for multiple sorts: .order_by(desc(Entry.amount), asc(Entry.date)).

Test it—run .all() or iterate. Boom, sorted.


Method 2: The Column’s Built-in desc() Method

Hate imports? Chain it:

python
query = (model.Session.query(model.Entry)
 .join(model.ClassificationItem)
 .join(model.EnumerationValue)
 .filter_by(id=c.row.id)
 .order_by(model.Entry.amount.desc())) # No import!

Same SQL output. JanBask Training calls this out for timestamps: .order_by(Order.timestamp.desc()).

Why choose this? Fewer lines, zero namespace fuss. Downside? Slightly longer if sorting multiples. Still, it’s my go-to for quick scripts.

And ascending? .asc() or omit—defaults to it.


Complete Example with Joins and Filters

Your query, fixed and battle-tested:

python
# Option 1: With import
from sqlalchemy import desc

entries = (model.Session.query(model.Entry)
 .join(model.ClassificationItem)
 .join(model.EnumerationValue)
 .filter_by(id=c.row.id)
 .order_by(desc(model.Entry.amount))
 .all())

# Option 2: No import
entries = (model.Session.query(model.Entry)
 .join(model.ClassificationItem)
 .join(model.EnumerationValue)
 .filter_by(id=c.row.id)
 .order_by(model.Entry.amount.desc())
 .all())

for entry in entries:
 print(entry.amount) # Highest first!

Paginates too? Slap on .offset(0).limit(10). Handles sqlite3 or my sql backends seamlessly—SQLAlchemy abstracts it.

Real-world tweak: Multiple columns? .order_by(desc(Entry.amount), Entry.date.asc()). Nulls last? .order_by(Entry.amount.desc().nulls_last()) in SQLAlchemy 2.0+.


Advanced Tips for SQLAlchemy Order By Desc

Sorting isn’t one-size-fits-all. Sql alchemy pros mix it up:

  • Expressions: Sort by computed fields? .order_by(desc(func.count(Entry.id).label('total')).
  • Related queries: Eagerload with .options(joinedload(Entry.classifications)) before sorting.
  • Performance: Indexes matter. CREATE INDEX ON entry (amount DESC) speeds sqlalchemy order by desc.
  • Alternatives: Raw SQL? text('ORDER BY amount DESC'), but ORM’s safer.
  • Chains: Window functions? .order_by(desc(Entry.amount.over(partition_by=Entry.category))).

Pitfalls? Case-sensitive strings—use func.lower(Entry.name).desc(). Dates? desc(Entry.created_at) for recents first.

Ties? Add secondary sorts. And for sqlmap or security? Sanitize inputs, but sorting’s harmless.

As of 2026, SQLAlchemy 2.0+ refines this—no breaking changes here.


Sources

  1. python - SQLAlchemy ORDER BY DESCENDING? - Stack Overflow
  2. SQLAlchemy ORDER BY DESCENDING
  3. Column Elements and Expressions — SQLAlchemy 2.0 Documentation
  4. How can I use “order_by” of Sqlalchemy to retrieve data in descending and ascending order?

Conclusion

Mastering SQLAlchemy order by desc boils down to desc()—import it or chain it—and your queries level up instantly. No more NameErrors, just crisp descending sorts across joins and filters. Experiment with both methods; you’ll find your favorite. Next time traffic spikes on high-value entries, you’ll thank this tweak.

Authors
Verified by moderation
Moderation
SQLAlchemy Order By Desc: How to Sort Descending