0

I have a flask app that retrieves data from a database. I would like to cache this data so I am not constantly requesting data from the database.

Currently I am using flask_caching and it is working, but ONLY for the individual document I request.

For example the database might contain 1000 rows, and I would like to cache ALL rows (not just one row, which is the behaviour now). I understand it is doing this, because the URL I am requesting specifies the doc_id.

My route in flask looks like this:

@site.route('/display/<doc_id>', methods=["GET", "POST"])
@cache.cached(query_string=True)
def display(doc_id):
    results = connect_to_db_get_ALL_results()
    return render_template("display.html")

The above code is simplified. I can see the cache IS working for a specific document (ie if I load the page http://localhost/display/1 , then click on the "Next" button on my rendered page to retrieve the next document (http://localhost/display/2), it will retrieve it from the database (not the cache), but it will cache what it just received from the database because when I click "previous document" on the rendered page (http://localhost/display/1), it will retrieve it from the cache.

Because my function "connect_to_db_get_ALL_results" actually returns all of the results I need for all docs.. What I would like to do is cache all of these documents (rather than just the current document in the URL). Such that if I decided to load http://localhost/display/994 it would select the data from the cache.

I have tried a few things (including using query_string and memoize, but neither of these things is what I need), I have also tried caching the function that returns ALL of the results, but this doesn't seem to work. Please help!

UPDATE: The way around this was to cache the function (that returns all results) rather than the route.

@site.route('/display/<doc_id>', methods=["GET", "POST"])
def display(doc_id):
    results = connect_to_db_get_ALL_results()
    return render_template("display.html")

@cache.cached(timeout=500, key_prefix='all_docs')
def connect_to_db_get_ALL_results()
    <code to fetch the data from the table>
Calamari
  • 29
  • 1
  • 9
  • Do you want to cache the routes before they have ever been called? I am not sure if that's what you're trying to achieve. Normally, they would be cached after they have been called at least once... – c8999c 3f964f64 Dec 09 '22 at 10:26
  • @c8999c3f964f64 thanks for the reply/question. Yes, that's what I am trying to do, let me update my question to make it clearer. – Calamari Dec 12 '22 at 07:48
  • I dont think that's possible, or at least not out of the box - a cache is generated after the first time it is used, it remembers the return value from the previous time. there is no previous time at the first time, unfortunately... – c8999c 3f964f64 Dec 12 '22 at 13:21

1 Answers1

0

The way around this was to cache the function (that returns all results) rather than the route.

@site.route('/display/<doc_id>', methods=["GET", "POST"])
def display(doc_id):
    results = connect_to_db_get_ALL_results()
    return render_template("display.html")

@cache.cached(timeout=500, key_prefix='all_docs')
def connect_to_db_get_ALL_results()
    <code to fetch the data from the table>
Calamari
  • 29
  • 1
  • 9
  • but if the endpoint is parameterised, the function returning the data also will need parameters, in this case, the doc_id, so your example doesn't make sense. – allor99 Feb 24 '23 at 14:21