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.

Reply via email to