Redis的Python实践,以及四中常用应用场景详解——学习董伟明老师的《Python Web开发实践》
# coding=utf-8
import json
from datetime import datetime
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
import redis
import pymysql
pymysql.install_as_MySQLdb()
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://web:web@localhost:3306/r'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
r = redis.StrictRedis(host='localhost', port=6379, db=0)
MAX_FILE_COUNT = 50
#数据模型,有id,name和uploadtime三个字段
class PasteFile(db.Model):
__tablename__ = 'files'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(5000), nullable=False)
uploadtime = db.Column(db.DateTime, nullable=False)
def __init__(self, name='', uploadtime=None):
self.uploadtime = datetime.now() if uploadtime is None else uploadtime
self.name = name
db.create_all()
#该函数对POST传入的id和name,写MySQL数据库,LPUSH到Redis中,并LTRIM裁剪保留MAX_FILE_COUNT个
@app.route('/upload', methods=['POST'])
def upload():
name = request.form.get('name')
pastefile = PasteFile(name)
db.session.add(pastefile)
db.session.commit()
r.lpush('latest.files', pastefile.id)
r.ltrim('latest.files', 0, MAX_FILE_COUNT - 1)
return jsonify({'r': 0})
#该视图函数截取start-limit个数据,通过json呈现在街面上,默认0-20就是最新插入的20条
@app.route('/lastest_files')
def get_lastest_files():
start = request.args.get('start', default=0, type=int)
limit = request.args.get('limit', default=20, type=int)
ids = r.lrange('latest.files', start, start + limit - 1)
files = PasteFile.query.filter(PasteFile.id.in_(ids)).all()
return json.dumps([{'id': f.id, 'filename': f.name} for f in files])
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000, debug=True)
随机生成100条数据:
from lastest_files import app, PasteFile, r
import time ,random, string
#随机生成100条name插入MySQl表,id自增
with app.test_client() as client:
for _ in range(1,101):
data = ''.join(random.sample(string.ascii_letters,10))+'_'+str(_)
print ('input data: ',data)
client.post('/upload',data={'name':data})
time.sleep(0.5)
测试结果:
# coding=utf-8
import string
import random
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
GAME_BOARD_KEY = 'game.board'
for _ in range(1000):
score = round((random.random() * 100), 2)
user_id = ''.join(random.sample(string.ascii_letters, 6))
#随机生成1000个用户,每个用户具有得分和用户名字,插入Redis的有序集合中
r.zadd(GAME_BOARD_KEY, score, user_id)
# 随机获得一个用户和他的得分
user_id, score = r.zrevrange(GAME_BOARD_KEY, 0, -1,
withscores=True)[random.randint(0, 200)]
print (user_id, score)
#用有序集合的ZCOUNT获取0-100的个数也就是所有人的数量,获取0-score分数段的人数,也就是这个用户分数超过了多少人
board_count = r.zcount(GAME_BOARD_KEY, 0, 100)
current_count = r.zcount(GAME_BOARD_KEY, 0, score)
print (current_count, board_count)
print ('TOP 10')
print ('-' * 20)
#用有序集合的ZREVRANGEBYSCORE返回指定区间的元素
#ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
for user_id, score in r.zrevrangebyscore(GAME_BOARD_KEY, 100, 0, start=0,
num=10, withscores=True):
print (user_id, score)
测试结果:
b'mgOvfl' 83.04 811 1000 TOP 10 -------------------- b'rbhXNd' 99.91 b'KJFELh' 99.88 b'cyjNrJ' 99.81 b'RXohkG' 99.64 b'SMVFbu' 99.51 b'FMBEgz' 99.5 b'ajxhdp' 99.45 b'QuMSpL' 99.33 b'IFYCOs' 99.31 b'VyWnYC' 98.74
# coding=utf-8
import time
import random
from datetime import datetime
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
ACCOUNT_ACTIVE_KEY = 'account:active'
r.flushall()
# r.delete(ACCOUNT_ACTIVE_KEY)
now = datetime.utcnow()
def record_active(account_id, t=None):
#第一次t自己生成,后面t接受传入的年月日
if t is None:
t = datetime.utcnow()
#Redis事务开始
p = r.pipeline()
key = ACCOUNT_ACTIVE_KEY
#组合了年月日三种键值,同时将三个键值对应字符串的account_id位置为1
#符合逻辑:该人在这一天登陆,肯定也在当前月登陆,也在当年登陆
for arg in ('year', 'month', 'day'):
key = '{}:{}'.format(key, getattr(t, arg))
p.setbit(key, account_id, 1)
#Redis事务提交,真正执行
p.execute()
def gen_records(max_days, population, k):
#循环每天的情况,从1-max_days天
for day in range(1, max_days):
time_ = datetime(now.year, now.month, day)
#每天随机生成k个数字,表示k个人活跃
accounts = random.sample(range(population), k)
#将这k个人对应在当天的字符串中修改,对应位置的bit置为1,表明这个天他有登陆过
for account_id in accounts:
record_active(account_id, time_)
#查看记录100万数据中随机选择10万活跃用户时的内存占用
def calc_memory():
r.flushall()
#执行前先看当前的内存占用
print ('USED_MEMORY: {}'.format(r.info()['used_memory_human']))
start = time.time()
#100万种选择10万,20天
gen_records(21, 1000000, 100000)
#记录话费时间
print ('COST: {}'.format(time.time() - start))
#添加记录后的内存占用
print ('USED_MEMORY: {}'.format(r.info()['used_memory_human']))
gen_records(29, 10000, 2000)
#这个月总的活跃用户数,直接查询记录月的key:bitcount "account:active:2016:11"
print (r.bitcount('{}:{}:{}'.format(ACCOUNT_ACTIVE_KEY, now.year, now.month)))
#今天的活跃用户数:bitcount "account:active:2016:11:23"
print (r.bitcount('{}:{}:{}:{}'.format(ACCOUNT_ACTIVE_KEY, now.year,
now.month, now.day)))
#随机找一个account_id为1200的用户,查看他是否登陆过:getbit "account:active:2016:11" 1200
account_id = 1200
print (r.getbit('{}:{}:{}'.format(ACCOUNT_ACTIVE_KEY, now.year, now.month),
account_id))
#getbit "account:active:2016:11" 10001
print (r.getbit('{}:{}:{}'.format(ACCOUNT_ACTIVE_KEY, now.year, now.month),
10001))
#获取当月1号和2号的建
keys = ['{}:{}:{}:{}'.format(ACCOUNT_ACTIVE_KEY, now.year, now.month, day)
for day in range(1, 3)]
#获取1号和2号的活跃的用户总数
r.bitop('or', 'destkey:or', *keys)
print (r.bitcount('destkey:or'))
#获取在1号和2号都活跃的用户数
r.bitop('and', 'destkey:and', *keys)
print (r.bitcount('destkey:and'))
测试结果:
9974 2000 1 3593 407
对应的Redis操作结果:
:" ( ::" ( :" ( :" ( ::","account:active:::" Invalid argument(s) ::" "account:active:::" ( > bitcount destkey:or ( ::" "account:active:::" ( > bitcount destkey:and (
Python代码中输出与Redis操作对应关系:
USED_MEMORY: 1.05M COST: 427.4658901691437 USED_MEMORY: 5.82M
Redis的Python实践,以及四中常用应用场景详解——学习董伟明老师的《Python Web开发实践》的更多相关文章
- Python安装与环境变量配置 入门详解 - 精简归纳
Python安装与环境变量配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 24 转载请注明出处!️ 目录 Python安装与环境变量配置 入门详解 - 精简归纳 一.下载Py ...
- maven常用插件配置详解
常用插件配置详解Java代码 <!-- 全局属性配置 --> <properties> <project.build.name>tools</proje ...
- 小白的Python之路 day5 time,datatime模块详解
一.模块的分类 可以分成三大类: 1.标准库 2.开源模块 3.自定义模块 二.标准库模块详解 1.time与datetime 在Python中,通常有这几种方式来表示时间:1)时间戳 2)格式化的时 ...
- Maya 常用环境变量详解
Maya 常用环境变量详解 前言: Maya 的环境变量让用户可以很方便的自定义 Maya 的功能. 在 Maya 的 Help 帮助文档中有专门的一个章节< Environment Varia ...
- Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)
Python 在子类中调用父类方法详解(单继承.多层继承.多重继承) by:授客 QQ:1033553122 测试环境: win7 64位 Python版本:Python 3.3.5 代码实践 ...
- Python中操作mysql的pymysql模块详解
Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...
- 七牛云存储Python SDK使用教程 - 上传策略详解
文 七牛云存储Python SDK使用教程 - 上传策略详解 七牛云存储 python-sdk 七牛云存储教程 jemygraw 2015年01月04日发布 推荐 1 推荐 收藏 2 收藏,2.7k ...
- Delphi中TStringList类常用属性方法详解
TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 先把要讨论的几个属性列出来: 1.CommaText 2.Delim ...
- Eclipse或Myeclipse常用快捷键组合详解
Eclipse 是一个开放源代码的.基于Java的可扩展开发平台,就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境.. Eclipse(Myeclipse)中有很多便于开发的快捷键 ...
随机推荐
- 练习:python 操作Mysql 实现登录验证 用户权限管理
python 操作Mysql 实现登录验证 用户权限管理
- weiphp踩坑记录
记录使用weiphp过程中遇到的问题及解决办法: 1.按照网上的教程创建插件怎么没有效果?replyText没有回复信息? 后台清除缓存即可!
- C#操作XML的通用方法总结
转载至http://www.cnblogs.com/pengze0902/p/5947997.html 1.创建xml 复制代码 /// <summary> /// 创建XML文档 /// ...
- 入门:Java Map<String,String>遍历及修改
重点:在使用Map时注意key-value,key用于检索value的内容. 在正常情况下,可以不允许重复:在java中分为2中情况,一是内存地址重复,另一个是不同的地址但内容相等. 在使用Map是一 ...
- zabbix监控Java 8080端口
linux下端口和服务是对应的,Java进程启动时默认监听8080端口,如果服务挂掉则8080端口就没有了. lsof -i:8080 端口,如果没有任何的输出,说明该端口不在工作. 想在zabbix ...
- Digester组件
刚认识Digester,记录一下: Digester随着Struts的发展以及其的公用性而被提到commons中独自立项,是apache的一个组件 apache commons-digester.ja ...
- Apache Shiro 学习记录3
晚上看了教程的第三章....感觉Shiro字符串权限很好用....但是教程举的例子太少了.....而且有些地方讲的不是很清楚....所以我也自己测试了一下....记录一下测试的结果.... (1) * ...
- juery学习总结(二)——juery操作页面元素
所有的操作都可以分为增.删.改.查四种,juery选择器代表查看的功能,那么剩下的操作就是对页面元素增.删.改.页面元素有3部分构成:标签,属性和内容,juery对元素的操作可以从这3方面入手. 一. ...
- SQL Server 2016 RC0 安装(超多图)
微软最新版本的数据库SQL Server 2016在2016年3月9日推出了RC0版本.已经提供了包括简体中文等多种语言版本,不过联机丛书还是英文版的.对OS的要求是WIN8,WIN10, WIN20 ...
- 【HTML5&CSS3进阶学习02】Header的实现·CSS中的布局
前言 我们在手机上布局一般是这个样子的: 其中头部对整个mobile的设计至关重要,而且坑也很多: ① 一般来说整个header是以fixed布局,fixed这个产物在移动端来说本身坑就非常多 ② 在 ...