利用memoize缓存到Redis出现多个参数同一个结果
在为后端输出加入Redis缓存的过程中出现的问题。
在我利用Flask-restful架构的后端中,理所当然的利用装饰器marshal_with对我的返回数据进行格式化输出。
举个最简单的例子:
from flask_restful import Resource, fields, marshal_with
fields = {
'id': fields.Integer,
'name': fields.String,
'bio': fields.String,
}
class Users(Resource):
@marshal_with(fields)
def get(self, user_id):
return session.query(User).filter(User.id=user_id).first()
这样子通过GET请求则会从数据库拿到的query对象会被marshal_with装饰城json数组返回(此处省略了主app添加资源然后运行,以及models的创建过程)。
在我想对这样一个资源请求添加缓存的时候,自然准备利用flask_cache.
而flask_cache的对象cache,主要两个装饰器(详细可参考:https://pythonhosted.org/Flask-Cache/):
1.cache.cached
2.cache.memoize
区别主要在于第二个在制作key的时候会考虑参数,那么因为我们这个有user_id,不同的用户请求在缓存当中不同,自然选择memoize,所以我一开始就这样写。
from flask_restful import Resource, fields, marshal_with
from flask_cache import Cache cache=Cache(......) #initial with app fields = {
'id': fields.Integer,
'name': fields.String,
'bio': fields.String,
} class Users(Resource):
@cache.memoize()
@marshal_with(fields)
def get(self, beacon_id):
return session.query(User).filter(User.id=user_id).first()
可是在测试过程中发现,对于不同的user_id,返回的都是同一个缓存结果。
几经波折,打印出来才发现是装饰器顺序导致memoize了marshal_with的装饰导致key一样。
那么如果我把这两个顺序交换,也就是说memoize放在marshal_with下面,可是这样子会造成一个新的问题,
缓存的数据是SQLAlchemy的查询结果,当你试图从缓存中恢复的时候则会造成:
“Parent instance <SomeClass> is not bound to a Session; lazy load operation…”
这个错误,最终,我选择了取消marshal_with装饰器:
from flask_restful import Resource, fields, marshal_with,marshal
from flask_cache import Cache cache=Cache(......) #initial with app fields = {
'id': fields.Integer,
'name': fields.String,
'bio': fields.String,
} class Users(Resource):
@cache.memoize()
def get(self, beacon_id):
return marshal(session.query(User).filter(User.id=user_id).first(),fields)
也就是说直接缓存marshal装饰后的结果。
在put post等修改数据库的操作后,利用cache.delete_memoized删掉缓存保证数据同步。
利用memoize缓存到Redis出现多个参数同一个结果的更多相关文章
- [python]mysql数据缓存到redis中 取出时候编码问题
描述: 一个web服务,原先的业务逻辑是把mysql查询的结果缓存在redis中一个小时,加快请求的响应. 现在有个问题就是根据请求的指定的编码返回对应编码的response. 首先是要修改响应的bo ...
- 【OF框架】缓存Session/Cookies/Cache代码调用api,切换缓存到Redis
准备 缓存服务在应用开发中最常用的功能,特别是Session和Cookies,Cache部分业务开发过程会使用到. 在负载均衡环境下,缓存服务需要存储到服务器. 缓存默认实现在内存在,可以通过配置切换 ...
- scrapy实现自动抓取51job并分别保存到redis,mongo和mysql数据库中
项目简介 利用scrapy抓取51job上的python招聘信息,关键词为“python”,范围:全国 利用redis的set数据类型保存抓取过的url,现实避免重复抓取: 利用脚本实现每隔一段时间, ...
- CentOS6.4 安装OpenResty和Redis 并在Nginx中利用lua简单读取Redis数据
1.下载OpenResty和Redis OpenResty下载地址:wget http://openresty.org/download/ngx_openresty-1.4.3.6.tar.gz Re ...
- [redis] session 保存到 redis 简单实现
参考资料: [session保存到redis简单实现]http://blog.csdn.net/ppt0501/article/details/46700221 [Redis学习]http://blo ...
- 针对缓存在Redis中的聊天消息的持久化方案分析
选型依据 数据库的选型主要考虑一下几个方面: 数据库本身是否收费 数据库后期维护成本 是否支持水平及垂直扩展,及扩展的容易程度 业务数据本身特性 使用此数据库的开发成本 由于此数据库主要用来存储缓存在 ...
- 如何将购物车信息存到Redis中?
存到Redis中,好处是速度快.毕竟写到硬盘需要更多的时间.加入购物车的功能,操作很频繁,可以通过Redis快速写入,移除,修改. 用什么方式呢? 传统的KEY,VALUE不太合适,每次增加修改,都要 ...
- 在Spring Controller中将数据缓存到session
Servlet方案 在Controller的方法的参数列表中,添加一个javax.servlet.http.HttpSession类型的形参.spring mvc会 自动把当前session对象注入这 ...
- nodejs express session用法(含保存到redis)
普通用法: var express = require('express'); var session = require('express-session'); var app = express( ...
随机推荐
- Shell parameter expansion
使用sh写一些小型的脚本会使工作更加简单.有部分内容可能大家都比較陌生(至少我是这样). 就是变量有关的參数展开,以下就是一些简单的描写叙述和使用方法.能够使代码更加简洁 展开运算符 替换运算 ${v ...
- OpenGLES 与 WebGL 中顶点属性的组织格式的误解 - 一个不好笑的笑话
版权声明:本文为博主原创文章,未经博主同意不得转载.转载联系 QQ 30952589.加好友请注明来意. https://blog.csdn.net/sleks/article/details/289 ...
- 【linux】新添加一块硬盘制作LVM卷并进行分区挂载
linux服务器新添加一块硬盘,可以直接将盘格式化挂载就能用,比如挂载在/usr/local目录,但是这样有一个弊端,就是如果这一块磁盘满了,后续想要扩容的话,不能继续挂载这个/usr/local挂载 ...
- golang字符串拼接性能对比
对比 +(运算符).strings.Join.sprintf.bytes.Buffer对字符串拼接的性能 package main import ( "bytes" "f ...
- 对于glut和freeglut的一点比较和在VS2013上的配置问题
先大概说一下glut.h和freeglut.h 首先要知道openGL是只提供绘图,不管窗口的,所以你需要给它一个绘图的区域(openGL能跨平台也与此有些关系) glut.h和freeglut.h都 ...
- hdu-5793 A Boring Question(二项式定理)
题目链接: A Boring Question Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java ...
- leetcode 19. Remove Nth Node From End of List(链表)
Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...
- Codeforces Gym 101190 NEERC 16 .D Delight for a Cat (上下界的费用流)
ls是一个特别堕落的小朋友,对于n个连续的小时,他将要么睡觉要么打隔膜,一个小时内他不能既睡觉也打隔膜 ,因此一个小时内他只能选择睡觉或者打隔膜,当然他也必须选择睡觉或打隔膜,对于每一个小时,他选择睡 ...
- bzoj1055玩具取名——区间DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1055 区间DP,注意初始化!! 因为没记忆化,TLE了一晚上,区间DP尤其要注意不重复递归! ...
- WPF TextBox PreviewTextInput handle IME (chinese)
今天调试自己写的WPF的Behavior, 是关于TextBox只能输入数据或者小数点的. 发现有个问题, 就是英文IME下字母等等都能过滤, 但是一旦切换到中文输入法, 就会发现在OnPreview ...