lru缓存在Flask App上的相同参数的应用程序运行之间不起作用

lru caching not working between application runs for same argument on Flask App

*编辑:刚刚意识到我在函数设计中犯了一个错误,我在我的 Class1 函数中重新实例化了 AppDAO,这就是导致意外行为的原因。我通过在 cache_call.

中打印 self 参数来解决这个问题

我有一个具有以下设计的 Flask 应用程序:

 from flask import Flask, request
 from Class1 import Class1
 from AppDAO import AppDAO
 
 app = Flask(__name__)

 def main():
   app.config['appDAO'] = AppDAO()
   app.run()

 @app.route('/app_route1',methods=['POST'])
 def app_route1():
     print("Running app route 1...")
     print(app.config['appDAO'].cache_call.cache_info())
     
     cache_param = request.json.get('cached_parameter')
     print("The cached parameter is: %s." % cache_param)

     class1 = Class1(app.config['appDAO'])

     for item in ['item1', 'item2']:
           class1.do_processing(item,cache_param)

Class1.py:

class Class1(object):
   def __init__(self, app_dao):
     self.app_dao = app_dao

   def do_processing(self, item, cache_param):
        print("Processing for item: %s..." % item)

        resp_cache = self.app_dao.cache_call(cache_param)
        print(self.app_dao.cache_call.cache_info())
        
        return resp_cache

AppDAO.py:

from functools import lru_cache
import mysql.connector 

class AppDAO(object):
  
  def __init__():
      self.conn = mysql.connector.connect('user1','password1','server1','database')
  
  @lru_cache(maxsize=4)
  def cache_call(self, cache_param):
     print("Running cache call with parameter: %s..." % cache_param)

     cursor = self.conn.cursor()
     cursor.execute("SELECT * FROM Table1 WHERE Column1 = `%s`;" % cache_param)
     rs = cursor.fetchall()

     return rs
       

如果我 运行 应用程序制作 post,AppDAO.cache_call 可以正常运行并输出以下内容 print 输出:

 Running app route 1...
 CacheInfo(hits=0, misses=0, maxsize=4, currsize=0)
 Processing items: item1...
 Running cache call with parameter: foo1...
 CacheInfo(hits=0, misses=1, maxsize=4, currsize=1)
 Processing items: item2...
 CacheInfo(hits=1, misses=1, maxsize=4, currsize=1)

但是我使用与 cache_call 相同的参数向分支创建另一个 post,我得到以下 print 输出:

 Running app route 1...
 CacheInfo(hits=1, misses=1, maxsize=4, currsize=1)
 Processing items: item1...
 Running cache call with parameter: foo1...
 CacheInfo(hits=1, misses=2, maxsize=4, currsize=2)
 Processing items: item2...
 CacheInfo(hits=2, misses=2, maxsize=4, currsize=2)
  

我 运行 使用 Anaconda QT Console 的应用程序,但如果我也使用 Anaconda Command Prompt,我会遇到以下缓存问题。任何人都可以推测为什么 lru_cache 在对应用程序进行新的 post 时不起作用,尽管缓存的调用仍在清除存储中?

注意

@lru_cache(maxsize=4)
def cache_call(self, cache_param):

正在包装一个方法,而不是一个函数。在您的示例中,self 将用作缓存键的一部分,它是 Class1 的一个实例,并且在每次路由处理程序调用时创建一次。结果是您没有获得预期的缓存

更新:我看错了代码。假设

for item in [item1, item2]:

打错了,应该是

for item in ['item1', 'item2']:

并且您 do_processing 有意不将 item(有所不同)传递给 cache_call,那么您所看到的与 lru_cache 的方式一致行为举止。

在第一次请求时,它会向缓存中添加一个东西 (request.json.get('cached_parameter')),将其计为 'item1' 未命中和 'item2' 命中。

在第二次请求时,request.json.get('cached_parameter') 是一个不同的对象。它被计为 'item1' 未命中,已添加(将 'currsize' 增加到 2)。对于 'item2',它被计为命中。

您期望什么行为?

不相关但值得一提:构建该查询的方式使您容易受到 SQL 注入攻击。考虑改用绑定参数。