pythonsqlalchemy

Selecting a specific column of a select query


I defined a Usr sqlalchemy table:

from sqlalchemy import Column, Integer, String, select
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class Usr(Base):  # user table
    __tablename__ = "usr"
    usr_id = Column(Integer, primary_key=True)
    usr_name = Column(String)
    usr_age = Column(Integer)

Let's say have two queries selecting users on their age or on their name:

q1 = select(Usr).where(Usr.usr_name.like("%Bob%"))
q2 = select(Usr).where(Usr.usr_age > 12)

Now I would like to construct a third query returning users that are returned either by q1 either by q2.

This obviously doesn't work since q1 and q2 return a 3-tuple:

q3 = select(Usr).where(Usr.usr_id.in_(q1) | Usr.usr_id.in_(q2))

Basically I would need something that returns me only a specific column of a select. But I'm stuck here. Any suggestion ?


Solution

  • q1 and q2 both select the whole row (select(Usr)), not just the usr_id. The in_() clause expects a subquery that returns only the relevant column, not a row.

    from sqlalchemy import Column, Integer, String, select, union
    from sqlalchemy.orm import declarative_base
    
    Base = declarative_base()
    
    class Usr(Base): 
        __tablename__ = "usr"
        usr_id = Column(Integer, primary_key=True)
        usr_name = Column(String)
        usr_age = Column(Integer)
    
    q1 = select(Usr).where(Usr.usr_name.like("%Bob%"))
    q2 = select(Usr).where(Usr.usr_age > 12)
    
    union_subquery = union(
        select(q1.subquery().c.usr_id),
        select(q2.subquery().c.usr_id)
    ).subquery()
    
    q3 = select(Usr).where(Usr.usr_id.in_(select(union_subquery.c.usr_id)))