Flask使用flask_cache缓存以及报错的解决办法

当数据库资源较多时,有些数据不是经常更新,或者更新较少的时候,我们为了降低服务器的压力可以使用cache缓存系统,而不是每次都去数据库进行查询,这样能够降低不少数据库压力,例如,导航、热门关键词排行等,这些基本很少去更新,所以我们都可以缓存到内存中,这样读取速度快,并且减少了数据库和CPU的压力

Flask框架一般都是使用flask_cache模块来缓存

安装方法是

pip install flask_cache

安装好以后,我们在我们的项目里面实例化一下就可以开始使用了。

from flask_cache import Cache
cache = Cache(app,config={'CACHE_TYPE': 'simple'})

然后就是这个对象下的几个装饰器讲解下

1.@cache.cached()装饰器

1).缓存视图函数

使用@cache.cached()装饰器,这个装饰器默认使用request.path作为cache_key,这个cache_key目前我用只是在删除的时候来使用下,应该还有其他用处,这里暂不扩展开来讲解

@cache.cached()装饰器还可以接收参数,如参数timeout设置缓存过期时间;参数unless接收一个Bool类型的值,如果设置为True将不会使用缓存机制;参数key_prefix替换默认的cache_key

2).缓存其他函数

使用@cache.cached()装饰器可以缓存其它非视图相关函数的结果,当使用@cache.cached()装饰器缓存非视图相关函数的结果时,建议传入参数key_prefix来替换默认的cache_key,否则它将会默认使用request.path作为cache_key

2.@cache.memoize()装饰器

在@cache.memoize()装饰器中,函数的参数也包含在cache_key中

上面讲的有点难懂,我简单的理解为,缓存视图函数可以使用@cache.cached()这个装饰器,注意要设置key_prefix

缓存普通函数,不带参数就和@cache.cached()一样,如果带参数就用@cache.memoize()装饰器

如果函数不接受参数那么@cache.cached()和@cache.memoize()就是一样的。

直接上我的实例代码:

#!/usr/local/bin/python3
#coding:utf-8
__author__ = 'merci'

from flask import Flask,Blueprint,request,jsonify,render_template
from urllib import request as rq
from aip import AipNlp
from common import formatTime,getThumb,getPage
from flask_cache import Cache
from model.mysql import database
import pymysql
import math
import json
app = Flask(__name__)
#定义手机版蓝图
wap = Blueprint('wap', __name__)
cache = Cache(app,config={'CACHE_TYPE': 'simple'})
db = database()

#SEO
@cache.cached(timeout=3600, key_prefix='cache_seo')
def seo():
    sql = """SELECT * FROM `v9_site`"""
    site = db.fetch_one(sql)
    return site

#导航
@cache.cached(timeout=3600, key_prefix='cache_nav')
def navigation():
    sql = """SELECT * FROM `v9_category` WHERE 1 ORDER BY `listorder` ASC"""
    nav = db.fetch_all(sql)
    navlist = []
    for val in nav:
    navlist.append({'catid':val[0], 'catname':val[9]})
    return navlist

#热门关键词
@cache.cached(timeout=3600, key_prefix='cache_hotkey')
def hotkeywords():
    sql = """SELECT * FROM `v9_keyword` WHERE 1 ORDER BY `videonum` DESC LIMIT 50"""
    hot = db.fetch_all(sql)
    return hot

#本类推荐
@cache.memoize(timeout=3600)
def localRec(catid):
    sql = """SELECT * FROM `v9_picture` WHERE `posids`=1 AND `catid`=%d ORDER BY `id` DESC LIMIT 10""" % catid
    result = db.fetch_all(sql)
    return result

然后跑起来,竟然报错了,我们看看错误代码

Traceback (most recent call last):
  File "app.py", line 5, in <module>
    from wap.views import wap
  File "./wap/views.py", line 18, in <module>
    cache = Cache(app,config={'CACHE_TYPE': 'simple'})
  File "/usr/local/python3/lib/python3.7/site-packages/flask_cache/__init__.py", line 121, in __init__
    self.init_app(app, config)
  File "/usr/local/python3/lib/python3.7/site-packages/flask_cache/__init__.py", line 156, in init_app
    from .jinja2ext import CacheExtension, JINJA_CACHE_ATTR_NAME
  File "/usr/local/python3/lib/python3.7/site-packages/flask_cache/jinja2ext.py", line 33, in <module>
    from flask.ext.cache import make_template_fragment_key
ModuleNotFoundError: No module named 'flask.ext'

然后查找资料解决,打开/usr/local/python3/lib/python3.7/site-packages/flask_cache/jinja2ext.py,然后转到33行

#from flask.ext.cache import make_template_fragment_key
from flask_cache import make_template_fragment_key

注释一行,增加一行OK了,原因是flask在python3.5以上导入模块的方式变了,按上述修改即可


最后再说下删除缓存的方法

#删除cache_seo缓存项
cache.delete('cache_seo')
#同时删除cache_nav和cache_hotkey两个缓存项
cache.delete_many('cache_nav', 'cache_hotkey')
#这里是删除缓存的localRec函数且参数为5的缓存项
cache.delete_memoized('localRec', 5)
# 清理所有缓存
cache.clear()


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://sulao.cn/post/575.html

我要评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。