How to order by case, descending?

Question:

I want to build this query using SQLAlchemy:

select * from t order by
case
    when t.x!=0 then t.y
    when t.x==0 then 0
end desc;

I tried the following:

db.session.query(t).order_by(
    db.func.desc(
        db.func.case([
            (t.x!=0, t.y),
            (t.x==0, 0)
        ]
    )
)

But it raised a ProgrammingError 'You have an error in your SQL syntax'. How can I write this case statement in SQLAlchemy?

Asked By: Hayes Pan

||

Answers:

The case function is not db.func.case, it is sqlalchemy.sql.expression.case.

Answered By: Hayes Pan

case is not accessed through SQLAlchemy’s func helper. Instead, import it directly from sqlalchemy, or if you’re using Flask-SQLAlchemy it’s available on db.

You can specify an else clause rather than a second when. You can call .desc() on an expression rather than wrapping it with desc(). SQLAlchemy 2 has deprecated the session.query interface in favor of constructing with select then executing.

The query using Flask-SQLAlchemy and SQLAlchemy 2 looks like:

query = db.select(t).order_by(db.case([(t.x != 0, t.y)], else_=0).desc()
result = db.session.execute(query)

Or the legacy query interface:

result = db.session.query(t).order_by(db.case([(t.x != 0, t.y)], else_=0).desc()

Or if not using Flask-SQLAlchemy:

import sqlalchemy as sa

query = sa.select(t).order_by(sa.case([(t.x != 0, t.y)], else_=0).desc()
result = session.execute(query)
Answered By: davidism
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.