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