Hello,
I have a bunch of tables with created_at columns and I would like to bake queries to retrieve counts of rows from them.
def _entities_created(model: Model, before: datetime) -> int:
baked_query = BAKERY(lambda session: session.query(model))
baked_query += lambda q: q.with_entities(func.count())
baked_query += lambda q: q.filter(model.created_at < bindparam("before"))
return baked_query(session()).params(before=before).scalar()
foos_created = partial(_entities_created, Foo)
bars_created = partial(_entities_created, Bar)
This doesn't work, and upon a minute of reflection, it's clear why: the passed-in value of model is cached in the baked query. If you call foos_created(...) first and then call bars_created(...), you'll get the count of the Foos, and vice versa. I've tried a few things to fix this:
- baked_query = BAKERY(lambda session: session.query(bindparam("model")))
- This "works" in that it runs, but shows the same problem as the original version.
- baked_query = BAKERY(lambda session: session.query()); baked_query += lambda q: q.select_from(bindparam("entity"))
- This raises an "ArgumentError: argument is not a mapped class, mapper, aliased(), or FromClause instance." at query compilation time (in _as_query())
Is what I'm trying to do here possible? Is there a way to get an aliased() or FromClause from a bindparam? Is there an alternative approach that would allow me to continue to use baked queries while not having to implement a separate *_entities_created() for every model I'm interested in?
The next problem would then be how to refer to model.created_at within the filter clause. Can that be handled with a bindparam too?
Thanks,
Scott