python操作redis
redis
安装:https://github.com/tporadowski/redis/releases/
一 python操作redis
1 普通链接
pip install redis
import redis
conn = redis.Redis(
host="localhost",
port=6379,
db=0,
password=None)
conn.set('name', 'lqz')
conn.close()
2 连接池链接
pool.py
import redis
# 做一个连接池,POOL 对象,应该是单例的,全局只有这一个对象
POOL = redis.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379, decode_responses=True)
from .pool import POOL
import redis
# 2 从池中拿链接
conn=redis.Redis(connection_pool=POOL)
# 3 使用链接操作redis
res=conn.get('name')
print(res)
# 4 关闭,把连接放回池中
conn.close()
二 redis字符串操作
import redis
conn = redis.Redis()
....
conn.close
1 set
- set(name, value, ex=None, px=None, nx=False, xx=False)
conn.set('age',18)
# ex使用:10s后过期,被清理掉
conn.set('hobby','篮球',ex=10)
# nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
conn.set('name','666',nx=True) # name存在,不会修改了
# xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
conn.set('name','666',xx=True)
conn.set('hobby','篮球',xx=True)
2 setnx(name, value)
-
等同于 conn.set(name,value,nx=True)
-
设置值,只有name不存在时,执行设置操作(添加),如果存在,不会修改
3 setex(name, value, time)
-
等同于 conn.set(name,value,ex=True)
-
设置过期时间过期时间秒
4 psetex(name, time_ms, value)
-
等同于 conn.set(name,value,px=True)
-
过期时间毫秒
5 mset(*args, **kwargs)
- 批量设置
conn.mset({'name': 'qcc', 'age': 19, 'height': 180})
6 get(name)
- 获取值
print(conn.get('weight'))
# 140
7 mget(keys, *args)
- 批量取值
res = conn.mget('name', 'age')
# ['qcc', '19']
res = conn.mget(['name', 'hobby', 'height'])
# ['qcc', None, '183']
8 getset(name, value)
- 设置新值并获取原来的值
res = conn.getset('name', 'aaa')
print(res)
# qcc
9 getrange(key, start, end)
-
区间:[start, end]
-
获取子序列(根据字节获取,非字符)
res = conn.getrange('name', 0, 1)
print(res)
# aa
10 setrange(name, offset, value)
- offset 字符串的索引,字节(一个汉字三个字节)
- 修改字符串内容,从指定字符串索引开始向后替换
conn.setrange('name', 1, '122')
print(conn.get('name'))
# a122
11 setbit(name, offset, value)
- offset,位的索引(将值变换成二进制后再进行索引)
- value,值只能是 1 或 0
- 对name对应值的二进制表示的位进行操作
12 getbit(name, offset)
- 获取name对应的值的二进制表示中的某位的值 (0或1)
13 bitcount(key, start=None, end=None)
- 获取name对应的值的二进制表示中 1 的个数
14 bitop(operation, dest, *keys)
- operation,AND(并) 、 OR(或) 、 NOT(非) 、 XOR(异或)
- dest, 新的Redis的name
- *keys,要查找的Redis的name
- 获取多个值,并将值做位运算,将最后的结果保存至新的name对应的值
15 strlen(name)
- 返回name对应值的字节长度(一个汉字3个字节)
conn.set('name','你好')
print(conn.strlen('name'))
# 6
16 incr(self, name, amount=1)
-
amount,自增数(必须是整数)
-
自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增
-
做计数器,性能高,单线程,没有并发安全问题,不会错错乱
conn.incr('age') # 每次加1
conn.incrby('age',2) # 每次加2
17 incrbyfloat(self, name, amount=1.0)
-
同incr
-
amount,自增数(浮点型)
conn.incrbyfloat('score',2.2) # 每次加2.2
18 decr(self, name, amount=1)
- amount,自减数(整数)
- 自减
conn.decr('age',2) # 每次减2
conn.decrby('age',2) # 每次减2
19 append(key, value)
- 在redis name对应的值后面追加内容
print(conn.get('name'))
# 你好
conn.append('name','_dd')
print(conn.get('name'))
# 你好_dd
三 redis hash操作
1 hset(name, key, value)
- name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
conn.hset('user-info-01','name','qcc')
conn.hset('user-info-01','age',19)
2 hset(name, mapping)
- 批量设置键值对
- mapping:字典
conn.hset('user-info-02',mapping={'name':'qcc','age':18})
3 hget(name,key)
- 在name对应的hash中获取根据key获取value
print(conn.hget('user-info-01', 'name'))
# qcc
4 hmget(name, keys, *args)
- 在name对应的hash中获取多个key的值,不存在则返回None
- keys,要获取key集合,如:['k1', 'k2', 'k3']
- *args,要获取的key,如:k1,k2,k3
print(conn.hmget('user-info-01','name','age','hobby'))
# ['qcc', '19', None]
print(conn.hmget('user-info-01',['name','age','hobby']))
# ['qcc', '19', None]
5 hgetall(name)
- 获取name对应hash的所有键值
print(conn.hgetall('user-info-01'))
# {'name': 'qcc', 'age': '19'}
6 hlen(name)
- 获取name对应的hash中键值对的个数
print(conn.hlen('user-info-01'))
# 2
7 hkeys(name)
- 获取name对应的hash中所有的key的值
print(conn.hkeys('user-info-01'))
# ['name', 'age']
8 hvals(name)
- 获取name对应的hash中所有的value的值
print(conn.hvals('user-info-01'))
# ['qcc', '19']
9 hexists(name, key)
- 检查name对应的hash是否存在当前传入的key
print(conn.hexists('user-info-01','age'))
# True
print(conn.hexists('user-info-01','aa'))
# False
10 hdel(name,*keys)
- 将name对应的hash中指定key的键值对删除,可以批量删除
print(conn.hgetall('user-info-01'))
# {'name': 'qcc', 'age': '19'}
conn.hdel('user-info-01','age')
print(conn.hgetall('user-info-01'))
# {'name': 'qcc'}
conn.hdel('user-info-01', 'age', 'name')
11 hincrby(name, key, amount=1)
- 自增name对应的hash中的指定key的值,不存在则创建key=amount
- 整数
print(conn.hgetall('user-info-01'))
# {'name': 'qcc', 'age': '3'}
conn.hincrby('user-info-01', 'age', 2)
print(conn.hgetall('user-info-01'))
# {'name': 'qcc', 'age': '5'}
12 hincrbyfloat(name, key, amount=1.0)
- 自增name对应的hash中的指定key的值,不存在则创建key=amount
- 浮点数
print(conn.hgetall('user-info-01'))
# {'name': 'qcc', 'age': '5', 'score': '2.20000000000000018'}
conn.hincrbyfloat('user-info-01', 'score', 2.2)
print(conn.hgetall('user-info-01'))
# {'name': 'qcc', 'age': '5', 'score': '4.40000000000000036'}
13 hscan(name, cursor=0, match=None, count=None)
- 增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆
- cursor,游标(基于游标分批取获取数据)
- match,匹配指定key,默认None 表示所有的key
- count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
res=conn.hscan('map_q',count=10)
print(res)
# (704, {'604': 'qcc_604', '776': 'qcc_776', '999': 'qcc_999', '757': 'qcc_757', '971': 'qcc_971', '797': 'qcc_797', '483': 'qcc_483', '331': 'qcc_331', '673': 'qcc_673', '463': 'qcc_463'})
res=conn.hscan('map_q',cursor=704,count=10)
print(res)
# (800, {'826': 'qcc_826', '691': 'qcc_691', '268': 'qcc_268', '353': 'qcc_353', '881': 'qcc_881', '179': 'qcc_179', '956': 'qcc_956', '459': 'qcc_459', '48': 'qcc_48', '783': 'qcc_783', '371': 'qcc_371'})
14 hscan_iter(name, match=None, count=None)
- 利用yield封装hscan创建生成器,实现分批去redis中获取数据
for item in conn.hscan_iter('map_q',count=10):
print(item)
# ('604', 'qcc_604')
# ......
# ('361', 'qcc_361')
四 redis list操作
1 lpush(name, values)
- 在name对应的list中添加元素,每个新的元素都添加到列表的最左边
conn.lpush('food', '鸡腿')
conn.lpush('food', '鸭腿')
conn.lpush('food', '牛肉')
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', '鸡腿']
2 rpush(name, values)
- 在name对应的list中添加元素,每个新的元素都添加到列表的最右边
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', '鸡腿']
conn.rpush('food','羊肉')
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', '鸡腿', '羊肉']
3 lpushx(name, value)
- 只有name已经存在时,值添加到列表的最左边
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', '鸡腿', '羊肉']
conn.lpushx('food','牛奶')
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', '鸭腿', '鸡腿', '羊肉']
4 rpushx(name, value)
- 只有name已经存在时,值添加到列表的最右边
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', '鸭腿', '鸡腿', '羊肉']
conn.rpushx('food', '猪肉')
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', '鸭腿', '鸡腿', '羊肉', '猪肉']
5 llen(name)
- name对应的list元素的个数
print(conn.llen('food'))
# 6
6 linsert(name, where, refvalue, value))
- 在name对应的列表的某一个值前或后插入一个新值
- where,BEFORE或AFTER(小写也可以)
- refvalue,标杆值 ,即:在它前后插入数据
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', '鸭腿', '鸡腿', '羊肉', '猪肉']
conn.linsert('food','before','鸭腿','AAA')
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', 'AAA', '鸭腿', '鸡腿', '羊肉', '猪肉']
conn.linsert('food','after','鸭腿','BBB')
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', 'AAA', '鸭腿', 'BBB', '鸡腿', '羊肉', '猪肉']
7 lset(name, index, value)
- 对name对应的list中的某一个索引位置重新赋值
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', 'AAA', '鸭腿', 'BBB', '鸡腿', '羊肉', '猪肉']
conn.lset('food', 2, 'XXX')
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', 'XXX', '鸭腿', 'BBB', '鸡腿', '羊肉', '猪肉']
8 lrem(name, value, num)
- 在name对应的list中删除指定的值
- num
- num = 0 删除列表中所有的指定值
- num = n 从前到后,删除n个;
- num =-n 从后向前,删除n个
print(conn.lrange('num', 0, -1))
# ['1', '1', 'a', '1', 'a', '1', 'a', '1', '1', '1']
conn.lrem('num', 2, '1') # 从前到后,删除2个;
print(conn.lrange('num', 0, -1))
# ['a', '1', 'a', '1', 'a', '1', '1', '1']
conn.lrem('num', -2, '1') # 从后向前,删除2个
print(conn.lrange('num', 0, -1))
# ['a', '1', 'a', '1', 'a', '1']
conn.lrem('num', 0, '1') # 删除列表中所有的指定值;
print(conn.lrange('num', 0, -1))
# ['a', 'a', 'a']
9 lpop(name)
- 在name对应的列表的左侧获取第一个元素并在列表中移除
print(conn.lrange('food', 0, -1))
# ['牛奶', '牛肉', '鸭腿', 'BBB', '鸡腿', '羊肉', '猪肉']
conn.lpop('food')
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', 'BBB', '鸡腿', '羊肉', '猪肉']
10 rpop(name)
- 在name对应的列表的右侧获取第一个元素并在列表中移除
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', 'BBB', '鸡腿', '羊肉', '猪肉']
print(conn.rpop('food')) # 猪肉
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', 'BBB', '鸡腿', '羊肉']
11 lindex(name, index)
- 在name对应的列表中根据索引获取列表元素
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', 'BBB', '鸡腿', '羊肉']
print(conn.lindex('food',2))
# BBB
12 lrange(name, start, end)
- 区间:[start, end]
- 在name对应的列表分片获取数据
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', 'BBB', '鸡腿', '羊肉']
print(conn.lrange('food', 1, 2))
# ['鸭腿', 'BBB']
13 ltrim(name, start, end)
-
区间:[start, end]
-
在name对应的列表中移除没有在区间(索引之间)的值
print(conn.lrange('food', 0, -1))
# ['牛肉', '鸭腿', 'BBB', '鸡腿', '羊肉']
conn.ltrim('food', 1, 2)
print(conn.lrange('food', 0, -1))
# ['鸭腿', 'BBB']
14 rpoplpush(src, dst)
- 从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
- src,取出并要移除元素的列表对应的name
- dst,要插入元素的列表对应的name
print(conn.lrange('food', 0, -1))
print(conn.lrange('num', 0, -1))
# ['鸭腿', 'BBB']
# ['a', 'a', 'a']
conn.rpoplpush('food', 'num')
print(conn.lrange('food', 0, -1))
print(conn.lrange('num', 0, -1))
# ['鸭腿']
# ['BBB', 'a', 'a', 'a']
15 blpop(keys, timeout)
- 用于从一个或多个列表中弹出元素,并在列表为空时阻塞等待元素的到来。
- 按照从左到右去pop对应列表的元素
print(conn.lrange('food', 0, -1))
# ['a', 'b', 'c']
res=conn.blpop('num')
print(res) # a
16 brpop(keys, timeout)
- 用于从一个或多个列表中弹出元素,并在列表为空时阻塞等待元素的到来。
- 按照从右向左去pop对应列表的元素
print(conn.lrange('food', 0, -1))
# ['a', 'b', 'c']
res=conn.brpop('num')
print(res) # c
17 brpoplpush(src, dst, timeout=0)
- 从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
- src,取出并要移除元素的列表对应的name
- dst,要插入元素的列表对应的name
- timeout,当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞
print(conn.lrange('num', 0, -1))
print(conn.lrange('food', 0, -1))
# ['BBB', 'a', 'a', 'a']
# ['鸭腿']
conn.brpoplpush('num', 'food')
print(conn.lrange('num', 0, -1))
print(conn.lrange('food', 0, -1))
# ['BBB', 'a', 'a']
# ['a', '鸭腿']
五 redis其他操作
1 delete(*names)
- 根据删除redis中的任意数据类型
print(conn.exists('name')) # 1
print(conn.exists('user-info-01')) # 1
conn.delete('name','user-info-01')
print(conn.exists('name')) # 0
print(conn.exists('user-info-01')) # 0
2 exists(name)
- 检测redis的name是否存在
print(conn.exists('aa')) # 0
print(conn.exists('age')) # 1
3 keys(pattern='*')
- KEYS * 匹配数据库中所有 key
- KEYS h?llo 匹配 hello , hallo 和 hxllo 等
- KEYS h*llo 匹配 hllo 和 heeeeello 等
- KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
print(conn.keys('foo*')) # ['food', 'foods']
4 expire(name ,time)
- 为某个redis的某个name设置超时时间 ,秒
conn.expire('age',5)
5 rename(src, dst)
- 对redis的name重命名为
conn.rename('food','foods')
6 move(name, db))
- 将redis的某个值移动到指定的db下
conn.move('foods',3)
7 randomkey()
- 随机获取一个redis的name(不删除)
print(conn.randomkey()) # score
8 type(name)
- 获取name对应值的类型
print(conn.type('food')) # string
print(conn.type('user-info-02')) # hash