CASE WHEN with ORM (SQLalchemy)

I am using SQLAlchemy with the ORM paragdim. I don't manage to find a way to do a CASE WHEN instruction. I don't find info about this on the web.

Is it possible ?


See sqlalchemy.sql.expression.case function and more examples on the documentation page. But it would look like this (verbatim from the documentation linked to):

case([(orderline.c.qty > 100, item.c.specialprice),
      (orderline.c.qty > 10, item.c.bulkprice)
    ], else_=item.c.regularprice)
case(value=emp.c.type, whens={
        'engineer': emp.c.salary * 1.1,
        'manager':  emp.c.salary * 3,
    })

edit-1: (answering the comment) Sure you can, see example below:

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True, autoincrement=True)
    first_name = Column(String)
    last_name = Column(String)

xpr = case([(User.first_name != None, User.first_name + " " + User.last_name),],
        else_ = User.last_name).label("full_name")

qry = session.query(User.id, xpr)
for _usr in qry:
    print _usr.fullname

Also see Using a hybrid for an example of case used in the hybrid properties.


I got this to work with an aggregate function, in this case func.sum

My Example Code

from sqlalchemy import func, case

my_case_stmt = case(
    [
        (MyTable.hit_type.in_(['easy', 'medium']), 1),
        (MyTable.hit_type == 'hard', 3)
    ]
)

score = db.session.query(
    func.sum(my_case_stmt)
).filter(
    MyTable.success == 1
)

return score.scalar()

My Use Case

MyTable looks like this:

|   hit_type     |  success |  
-----------------------------  
|   easy         |   1      |  
|   medium       |   1      |  
|   easy         |   0      |  
|   hard         |   1      |  
|   easy         |   0      |
|   easy         |   1      |  
|   medium       |   1      |  
|   hard         |   1      |

score is computed as such: score = num_easy_hits + num_medium_hits + (3 * num_hard_hits)

4 successful easy/medium hits and 2 successful hard hits gives you (4 + (2*3)) = 10