Implementation of an lru_cache() decorator that ignores the first argument

Chris Angelico rosuav at gmail.com
Wed Sep 28 17:11:55 EDT 2022


On Thu, 29 Sept 2022 at 05:36, Robert Latest via Python-list
<python-list at python.org> wrote:
> in a (Flask) web application I often find that many equal (SQLAlchemy) queries
> are executed across subsequent requests. So I tried to cache the results of
> those queries on the module level like this:
>
>     @lru_cache()
>     def query_db(db, args):
>         # do the "expensive" query
>         return result
>
> ...
> This is what I came up with. I'm quite happy with it so far.  Question: Am I
> being too clever? is it too complicated? Am I overlooking something that will
> come back and bite me later? Thanks for any comments!
>
> def lru_ignore_first(timeout=0, **lru_args):
> ...

I think this code is fairly specific to what you're doing, which means
the decorator won't be as reusable (first hint of that is the entire
"timeout" feature, which isn't mentioned at all in the function's
name). So it's probably not worth trying to do this multi-layered
approach, and it would be as effective, and a lot simpler, to just
have code at the top of the query_db function to do the cache lookup.
But you may find that your database is *itself* able to do this
caching for you, and it will know when to evict from cache. If you
really have to do it yourself, keep it really really simple, but have
an easy way *in your own code* to do the cache purge; that way, you
guarantee correctness, even at the expense of some performance.

In terms of overall database performance, though: are you using
transactions correctly? With PostgreSQL, especially, the cost of doing
a series of queries in one transaction is barely higher than doing a
single query in a transaction; or, putting it the other way around,
doing several sequential transactions costs several times as much as
doing one combined transaction. Check to see that you aren't
accidentally running in autocommit mode or anything. It could save you
a lot of hassle!

ChrisA


More information about the Python-list mailing list