On 10/23/2016 06:02 AM, Anton Baranenko wrote:
Hi all,
based on the successful progress with my previous topic "Using
BakedQuery with joined subqueries" (thanks again Mike!) I have the next
question.
For some of my queries conditions logic is generated based on certain
parameters. For example, I have a JSONB field that contains custom
fields from the user. I have then "saved searches" defined by users to
search on the custom field.
Now based on the "saved search ID" my function will generate a query.
The logic roughly is:
def generate_saved_search_query(saved_search_id):
conditions = self.get_saved_search_conditions(saved_search_id)
for condition in conditions:
query = query.filter(condition)
the 'generate_saved_search_query' function is idempotent for any
parameter value. Searching for any particular saved_search_id occurs
frequently => it makes sense to cache the query.
The question is - how can I used BakedQuery with this setup? From the
source I can guess I should use add_criteria / with_criteria, but in the
unit tests / documentation I could not find an example of doing so with
the function parameter values.
OK well for a "baked" query, again we are making a cache key based on
the inputs. So keying on a list of conditions, first off keep in mind
if you have dozens of different conditions in any possible order /
combination, that would represent an explosion of cache keys beyond what
would allow the baked system to be useful.
the next thing is that if this is a list of things, the "baked" system
is usually going to use the callable you pass it as the cache key
itself, but in Python when we build a callable function inside of a
loop, it won't work if you did this:
for condition in conditions:
query += lambda q: somefunc(condition)
because "condition" keeps changing. normally we need to instead do it like:
for condition in condtions:
query += make_func(condition)
where make_func() returns the lambda that has a local variable
namespace. But that means the lambda is different every time, which
means your cache key is blown up. So! this is not as simple. There
is a way to do it, which is that baked allows for a second "args" that
allows you to augment the cache key. You'd roll your whole loop into a
single callable and also make a single cache key:
cache_key = tuple([str(condition) for condition in
sorted(conditions)])
def add_conditions(q):
for condition in conditions:
q = q.filter(condition)
return q
baked_query.add_criteria(add_conditions, cache_key)
I would note that the above concept is very advanced usage of this API,
so I'd make sure to test that it's coming out correctly. I might even
peek into the dictionary inside of the "bakery" to see that the keyspace
is forming as expected.
Thank you for any help,
Anton
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and
Verifiable Example. See http://stackoverflow.com/help/mcve for a full
description.
---
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to sqlalchemy+unsubscr...@googlegroups.com
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.