Reputation: 21
Two models:
class this(DeclarativeBase):
__tablename__ = 'this'
'Columns'
id = Column(Integer, primary_key=True)
'Relations'
that = relation('that', foreign_keys=id, backref='this')
class that(DeclarativeBase):
__tablename__ = 'that'
'Columns'
id = Column(Integer, primary_key=True)
this_id = Column(Integer, ForeignKey('this.id'))
I want to run this simple SQL Query:
SELECT id, (SELECT COUNT(*) FROM that WHERE this_id = this1.id) AS thatcount FROM this AS this1
I can achieve the same RESULTS in sqlalchemy by doing:
results = session.query(model.this.id,
func.count(model.that.id).label('thatcount')) \
.join(model.that) \
.group_by(model.this.id)
BUT, the resultant SQL is not what I want:
SELECT
this.id AS this_id,
count(that.id) AS thatcount
FROM this
INNER JOIN that ON this.id = that.this_id
GROUP BY this.id
I am missing a couple of fundamental ideas in sqlalchemy...
1) How do I "label" tables in FROM clauses? 2) How do I create subqueries that reference results from the parent query?
Hopefully this is something simple that I am just not understanding, as I'm relatively new to sqlalchemy... Of course I can just run raw SQL, but I am impressed by sqlalchemy and I'm sure this is possible.
Any help would be much appreciated!
Upvotes: 2
Views: 3297
Reputation: 76962
qry = select([
this.id,
select([func.count().label('xx')], this.id == that.this_id).as_scalar().label('thatcount'),
])
produces:
SELECT this.id, (SELECT count(*) AS xx
FROM that
WHERE this.id = that.this_id) AS thatcount
FROM this
To answer your questions directly:
label()
whereclause
of the select
to indicate the join condition between the main query and the subquery.Note that I prefer func.count(that.id)
to func.count()
though, as it is more explicit.
Upvotes: 3