python-redis
使用python操作Redis
安装
pip install redis
简单使用
from redis import Redis
# 实例化,创建连接
conn = Redis("127.0.0.1",6379,)
# 设置key
conn.set("key1","123")
# 取值
ret = conn.get("key1")
print(ret)
使用连接池
import redis
# 创建redis连接池
pool = redis.ConnectionPool(host="127.0.0.1",port=6379,max_connections=100)
# 从池中获取一个连接
conn = redis.Redis(connection_pool=pool)
ret = conn.get("key1")
print(ret)
1 String方法
在内存中按照一个name对应一个value来存储。
set
存储一条数据。
def set(self, name, value, ex=None, px=None, nx=False, xx=False, keepttl=False)
参数:
- name:键
- value:值
- ex:过期时间(秒)
- px:过期时间(毫秒)
- nx:如果为True,只有name不存在时,当前set操作才执行。值存在,就修改不了,执行没效果
- xx:如果为True,只有name存在时,当前set操作才执行。值存在才能修改,值不存在,不会设置新值
- keepttl:如果为True,保留之前给这个key设置的过期时间(redis6.0版本新增)
与之相关的命令:
setnx(name, value):相当于set默认将nx参数设为True
setex(name, value, time):相当于set必须传一个过期时间(秒)
psetex(name, time_ms, value):相当于set必须传一个过期时间(毫秒)
mset
批量存储。
def mset(self, mapping)
参数:
- mapping:传入一个字典。字典内的键值必须是字符串格式,或者能够被str()方法转成字符串
get
根据name获取单个值。
def get(self, name)
参数:
- name:键
mget
批量获取值。
def mget(self, keys, *args)
支持批量传入
# 举例
# 推荐传入包含key的列表
ret = conn.mget("key1","key2","key3")
ret = conn.mget(["key1","key2","key3"])
getset
获取原来的值,并传入新值。
def getset(self, name, value)
参数:
- name:键
- value:值
getrange
按字节划定区间,取子串。
def getrange(self, key, start, end)
参数:
- key:键
- start:起始位置
- end:终止位置
# 举例
ret = conn.getrange("key1",0,1)
# 闭区间,即区间[0,1],单位是字节(不是字符)
setrange
修改字符串内容,从起始位置开始向后替换(超出原有长度则增加)
def setrange(self, name, offset, value)
参数:
- name:键
- offset:起始位置(从0开始,按字节,1汉字为3字节)
- value:要设置的值
strlen
返回name对应值得长度(字节为单位)
def strlen(self, name)
setbit、getbit、bitcount、bitop
比特操作,不常用。
incr
将name对应的值增加amount;如果name对应为空,则将它初始化为amount
def incr(self, name, amount=1)
默认每执行一次,就自增1
amount可以设置为负数,实现decr相同功能。
incrbyfloat
将name对应的值增加amount;如果name对应为空,则将它初始化为amount(浮点型)
def incrbyfloat(self, name, amount=1.0)
decr
与incr对应,自减。
def decr(self, name, amount=1)
append
在key对应的值后面追加value
def append(self, key, value):
2 Hash方法
在内存中按照一个name对应一个字典来存储
hset
name对应的hash中设置一个键值对(不存在,则创建;存在,则修改)
def hset(self, name, key=None, value=None, mapping=None):
参数:
- mapping:接受一个字典,可以传入多个值。(**貌似python3.8以后支持)
conn.hset("name","k1","v1",{"k2":"v2","k3":"v3"})
hmset
在name对应的hash中批量设置
举例:
ret = conn.hmset(name="name",mapping={"k2":"v2","k3":"v3"})
hget
获取name中的key对应的值
def hget(self, name, key)
hmget
批量获取
def hmget(self, name, keys, *args)
参数:
- keys:要获取key集合,如:['k1', 'k2', 'k3']
- args:要获取的key,如:k1,k2,k3
举例:
# 两种方式都可以
conn.hmget("name",['k1', 'k2', 'k3'])
conn.hmget("name",'k1', 'k2', 'k3')
hgetall
获取name对应hash的所有键值
def hgetall(self, name)
hlen
获取name对应的hash中键值对的个数
def hlen(self, name)
hkeys、hvals
获取name对应的所有key或者value值得
def hkeys(self, name)
def hvals(self, name)
hexists
检查name对应的hash是否存在当前传入的key
def hexists(self, name, key)
存在返回True,不存在返回False
hdel
将name对应的hash中指定key的键值对删除
def hdel(self, name, *keys)
keys可以是列表传入多个
hincrby
自增name对应的hash中的指定key的值,不存在则创建key=amount
def hincrby(self, name, key, amount=1)
hincrbyfloat
浮点型自增,其他同上
def hincrbyfloat(self, name, key, amount=1.0)
hscan
增量式迭代获取。对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完。
def hscan(self, name, cursor=0, match=None, count=None)
参数:
- name:键
- cursor:游标(默认从0开始)基于游标获取数据
- match:匹配指定key,默认None 表示所有的key
- count:每次分片最少获取个数,默认None表示采用Redis的默认分片个数
举例:
# 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
# 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
# ...
# 直到返回值cursor的值为0时,表示数据已经通过分片获取完毕
hscan_iter
利用yield封装hscan创建生成器,实现分批去redis中获取数据
def hscan_iter(self, name, match=None, count=None)
参数:
- name:键
- match:匹配指定key,默认None 表示所有的key
- count:每次分片最少获取个数,默认None表示采用Redis的默认分片个数
举例:
for item in conn.hscan_iter('xx'):
print item
如果想取回所有数据,不建议使用hgetall,建议使用hscan_iter
3 List方法
在内存中按照一个name对应一个列表来存储。
lpush、rpush
在name对应的list中添加元素,每个新的元素都添加到列表的最左边或者最右边
def lpush(self, name, *values)
def rpush(self, name, *values):
举例:
r.lpush('name', 11,22,33)
# 保存顺序为: 33,22,11
r.rpush('name', 11,22,33)
# 保存顺序为: 11,22,33,
lpushx、rpushx
在name对应的list中添加元素,只有name存在时,每个新的元素会添加到列表的最左边或者最右边
def rpush(self, name, *values)
def rpushx(self, name, value)
lpop、rpop
在name对应的列表的左侧或者右侧获取第一个元素并在列表中移除,返回值则是第一个元素
def lpop(self, name)
def rpop(self, name)
linsert
在name对应的列表的某一个值前或后插入一个新值
def linsert(self, name, where, refvalue, value)
参数:
- name:键
- where:BEFORE或AFTER(小写也可以)
- refvalue:参考值。在它的前后插入数据(如果存在多个,以找到的第一个为准)
- value:要插入的值
lset
对name对应的list中的某一个索引位置重新赋值
def lset(self, name, index, value)
参数:
- name:键
- index:list的索引位置
- value:要设置的值
lrem
在name对应的list中删除指定的值
def lrem(self, name, count, value)
参数:
-
name:键
-
count:
count > 0: 从头到尾删除count个value count < 0: 从尾到头删除count个value count = 0: 删除所有value
-
value:要删除的值
lindex
在name对应的列表中根据索引获取列表元素
def lindex(self, name, index)
lrange
在name对应的列表分片获取数据,从start到end
def lrange(self, name, start, end)
参数:
- name:值
- start:索引的起始位置,可以是负数
- end:索引结束位置,可以是负数
ltrim
在name对应的列表中移除没有在start-end索引之间的值,闭区间
ltrim(self, name, start, end)
参数:
- name:值
- start:索引的起始位置,可以是负数
- end:索引结束位置,可以是负数(大于列表长度,则代表不移除任何)
rpoplpush
从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
def rpoplpush(self, src, dst)
参数:
- src:要取数据的列表的name
- dst:要添加数据的列表的name
blpop、brpop
b表示阻塞,将多个列表排列,按照从左到右去pop对应列表的元素(l);按照从右到左去pop对应列表的元素(r)
def blpop(self, keys, timeout=0)
def brpop(self, keys, timeout=0)
参数:
- keys:所有的name
- timeout:超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
应用场景:
# 爬虫实现简单分布式:多个url放到列表里,往里不停放URL,程序循环取值,但是只能一台机器运行取值,可以把url放到redis中,多台机器从redis中取值,爬取数据,实现简单分布式
brpoplpush
从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
def brpoplpush(self, src, dst, timeout=0)
参数:
- src:取出要移除元素的列表对应的name
- dst:要插入元素的列表对应的name
- timeout:超时时间,当src对应列表中没有数据时,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
自定义增量迭代
# 由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要:
# 1、获取name对应的所有列表
# 2、循环列表
# 但是,如果列表非常大,那么就有可能在第一步时就将程序的内容撑爆,所有有必要自定义一个增量迭代的功能:
import redis
conn=redis.Redis(host='127.0.0.1',port=6379)
# conn.lpush('test',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
# conn.flushall()
def scan_list(name,count=2):
index=0
while True:
data_list=conn.lrange(name,index,count+index-1)
if not data_list:
return
index+=count
for item in data_list:
yield item
print(conn.lrange('test',0,100))
for item in scan_list('test',5):
print('---')
print(item)
4 set方法
Set集合就是不允许重复的列表。
sadd
name对应的集合中添加元素
def sadd(self, name, *values)
scard
获取name对应的集合中元素个数
def scard(self, name)
sdiff
返回一个集合,该集合石传入集合之间的差集。
def sdiff(self, keys, *args):
sdiffstore
返回一个集合,该集合石传入集合之间的差集。把这个集合存储到新dest的集合中
def sdiffstore(self, dest, keys, *args)
sinter
返回一个集合,该集合石传入集合之间的交集。
def sinter(self, keys, *args)
sinterstore
返回一个集合,该集合石传入集合之间的交集。把这个集合存储到新dest的集合中
def sinterstore(self, dest, keys, *args)
sismember
检查value是否是name对应的集合的成员
def sismember(self, name, value)
smembers
返回集合name中的所有成员。
def smembers(self, name)
smove
将某个成员从一个集合中移动到另外一个集合
将value从src移动到dst
def smove(self, src, dst, value)
spop
从集合的右侧(尾部)移除count个成员name,并将其返回
def spop(self, name, count=None)
srandmember
从name对应的集合中随机获取number个元素
如果number不指定,就随即返回一个;如果指定,且小于集合长度,则返回指定的个数;如果大于集合长度,就返回整个集合。
def srandmember(self, name, number=None)
srem
在name对应的集合中删除某些值
def srem(self, name, *values)
sunion
获取keys指定的所有集合的并集
def sunion(self, keys, *args)
sunionstore
返回一个集合,该集合石传入集合之间的并集。把这个集合存储到新dest的集合中
def sunionstore(self, dest, keys, *args)
5 SortedSet方法
SortedSet就是有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd
def zadd(self, name, mapping, nx=False, xx=False, ch=False, incr=False)
zcard
def zcard(self, name):
zcount
def zcount(self, name, min, max):
zincrby
def zincrby(self, name, amount, value):
zrange
def zrange(self, name, start, end, desc=False, withscores=False,score_cast_func=float):
zrank
def zrank(self, name, value):
zrangebylex
def zremrangebylex(self, name, min, max):
zrem
def zrem(self, name, *values):
zremrangebyrank
def zremrangebyrank(self, name, min, max):
zremrangebyscore
def zremrangebyscore(self, name, min, max):
zremrangebylex
def zremrangebylex(self, name, min, max):
zscore
def zscore(self, name, value):
zinterstore
def zinterstore(self, dest, keys, aggregate=None):
zunionstore
def zunionstore(self, dest, keys, aggregate=None):
zscan
def zscan(self, name, cursor=0, match=None, count=None,score_cast_func=float):
zscan_iter
def zscan_iter(self, name, match=None, count=None,score_cast_func=float):
6 其他方法
delete
删除给定的一个或多个键,不存在的会被忽略
def delete(self, *names)
exists
检查给定的键是否存在
def exists(self, *names)
keys
获取符合匹配条件的所有keys
def keys(self, pattern='*'):
# KEYS * 匹配数据库中所有 key 。
# KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
# KEYS h*llo 匹配 hllo 和 heeeeello 等。
# KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 key ,你最好还是用 Redis 的集合结构(set)来代替
expire
为给定name设置生存时间,当name过期时(生存时间为 0 ),它会被自动删除。time为时间(单位秒)
def expire(self, name, time):
rename
重命名key。将src重命名为dst
def rename(self, src, dst):
move
将某个值移动到指定的db下
def move(self, name, db):
randomkey
随机获取一个name(不删除)
def randomkey(self):
type
获取name对应值的类型
def type(self, name):
scan
增量迭代获取,与zscan和hscan同理
def scan(self, cursor=0, match=None, count=None, _type=None):
scan_iter
利用yield封装scan创建生成器,实现分批去redis中获取数据
def scan_iter(self, match=None, count=None, _type=None):
7 管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline是原子性操作。
import redis
pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True) # transaction=true 开启事务
pipe.multi() # 标记着事物的开启
pipe.set('name', 'xxx')
pipe.set('age', '18')
pipe.execute() # 只有到这里才执行,执行完事物结束
有关更多操作,查看中文文档
8 Django中使用redis
方式一:
utils文件夹下,建立redis_pool.py
import redis
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379,password='1234',max_connections=1000)
视图函数中使用:
import redis
from django.shortcuts import render,HttpResponse
from utils.redis_pool import POOL
def index(request):
conn = redis.Redis(connection_pool=POOL)
conn.hset('kkk','age',18)
return HttpResponse('设置成功')
def order(request):
conn = redis.Redis(connection_pool=POOL)
conn.hget('kkk','age')
return HttpResponse('获取成功')
方式二:
安装django-redis模块官方github
pip3 install django-redis
setting里配置:
# redis配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
# "PASSWORD": "123",
}
}
}
视图函数:
from django_redis import get_redis_connection
conn = get_redis_connection('default')
print(conn.hgetall('xxx'))
本文来自博客园,作者:yyyz,转载请注明原文链接:https://www.cnblogs.com/yyyzyyyz/p/15643187.html