python操作redis

python操作redis

Python操作Redis之普通连接

1. 下载模块
	pip install redis
2. 简单使用
    from redis import Redis
    conn = Redis()	# 默认链接本地端口号为6379的redis数据库
    ret = conn.set('name', 'UPythonFish')	# 设置一个值,name=UPythonFish
    print(ret)	# 设置成功返回true

Python操作Redis之连接池

# redis_Pool
import redis
# 造一个池子,最多能放100个连接
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=100,  decode_responses=True)
'''
需要注意的是,由于redis在6.0版本之前是单线程模式,因此POOL必须是单例模式
解决方法有两种:
	1. python中的模块就是天然的单例模式,因此只需要将连接池封装成一个模块即可
	2. 写成一个类,生成的对象也是单例模式
decode_responses=True :  取出来的数据自动装换为str类型,有连接池的时候需要放在连接池
'''
# redis_con
from redis import Redis
from redis_Pool import POOL

conn = Redis(connection_pool=POOL)

ret = conn.get('name')
print(ret)操作之String操作

python操作之String操作

  1. set的使用
1.
    conn.set('height', '165', nx=True)
    conn.set('height1', '175', ex=1)
    conn.set('height2', '185', px=1000)
    conn.set('height3', '195', xx=True)
'''
        ex: 过期时间(秒)
        px: 过期时间(毫秒)
        nx: 如果设置为True, 只有name不存在时,当前set操作才执行,值存在,就不执行
        xx: 如果设置为True, 只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值 
    '''
2. setnx(self, name: _Key, value: _Value) -> bool: 等同于 set(nx=True) 	
3. setex(self, name: _Key, time: int | timedelta, value: _Value) -> bool: 等同于set(ex=)
4. psetex(self, name, time_ms, value): 等同于: set(px)
5. mset(self, mapping: Mapping[_Key, _Value]) -> Literal[True]: 
    # Mapping的意思是把值以字典的形式批量传入
    conn.mset({'name1':'11','name3':'dasfd'})
  1. get的使用
1. get(self, name: _Key) -> _StrType | None: # 放入一个key返回一个值
    
2. mget(self, keys: _Key | Iterable[_Key], *args: _Key) -> list[_StrType | None]:
    # Iterable[_Key] 传入一个可迭代对象,建议是列表类型,一次获取多个值,没有返回None
    ret=conn.mget(['name11','name4','name31'])
    ret1=conn.mget(('name1','name','name3'))
    print(ret, ret1)
    # [None, None, None] [b'11', b'UPythonFish', b'dasfd']
3. getset(self, name, value) -> _StrType | None:
    # 传入一个name和一个值,若name存在则将其取出来并修改为value,
    # 若name不存在在,则返回None并创造一个name,把value传入
4. getrange(self, key, start, end):   # 前闭后闭区间
    ret = conn.getrange('name', 0, 2)
    ret1 = conn.get('name')
    print(ret, ret1)
    # UPy UPythonFish
5. getbit(self, name: _Key, offset: int) -> int: 
    # 获取该数据二进制格式指定位置的数字,返回值只有0和1
  1. 其他操作
incr :用于统计网站访问量,页面访问量,接口访问量
incr(self, name: _Key, amount: int = ...) -> int: ...
	conn.incr('name1')  # 只要一执行,数字加1,也可以指定参数
	conn.incr('name1', 5) # 数字加5
	conn.incr('name1', -3) # 数字减3
    
decr(self, name, amount=...) -> int:     与incr相反
conn.append('name1','oo')  # 在字符串后面追加
  1. 总结
字符串操作重点是:
    set、mset、get、mget、incr、decr、append

python操作之Hash操作

# 设置hash数据一次只能设置一组值,若k存在,则修改
hset(self, name: _Key, key: _Key, value: _Value, mapping: Mapping[_Key, _Value] | None = ...) -> int: ...
	conn.hset('hash1','name','python')  # key不可以重复
# 批量添加键值对
hmset(self, name: _Key, mapping: Mapping[_Key, _Value]) -> bool: 
    conn.hmset('hash2',{'key1':'value1','key2':'value2'})
    
# 根据name和key值获取val值  只能取一个  
hget(self, name: _Key, key: _Key) -> _StrType | None: 
# 根据name和key获取val值,可以同时获取多个key对应的val值,没有返回None
hmget(self, name: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> list[_StrType | None]: ...    
# 根据name值获取所有的值,以字典的形式返回 不建议使用
hgetall(self, name: _Key) -> dict[_StrType, _StrType]:    
# 根据name获取所有的值,生成一个迭代器,推荐使用
hscan_iter(self, name, match=..., count=...): ...
# 根据key值删除val值,可以放多个
hdel(self, name: _Key, *keys: _Key) -> int: ...
# 判断key值是否存在
hexists(self, name: _Key, key: _Key) -> bool: ...
# val值必须是整数,给表中值+给定值(int类型),可以是负数
hincrby(self, name: _Key, key: _Key, amount: int = ...) -> int: 
    conn.hincrby('hash1', 'name1',5)
# val值必须是数值类型,给表中值+给定值(int和float类型),可以是负数 
hincrbyfloat(self, name: _Key, key: _Key, amount: float = ...) -> float:
# 获取表中所有的key值    
hkeys(self, name: _Key) -> list[_StrType]: ...
# 获取表中所有的val值
hvals(self, name: _Key) -> list[_StrType]: ...    
# 统计表中key的数量
hlen(self, name: _Key) -> int: ...
# 设置值,只有key不存在时,执行设置操作(添加),如果存在,不会修改
hsetnx(self, name: _Key, key: _Key, value: _Value) -> int: ...

重点掌握

hset、hget、hmset、hmget、hincrby、区分hgetall和hscan_iter

python操作之List操作

# 从左边插入数据,可以是多条,返回值是数据列表长度
lpush(self, name: _Value, *values: _Value) -> int: ...
    conn.lpush('list1',1,2,3,4,5)
# 插入一个数据,必须name值存在才能放    
lpushx(self, name, value): ...
# 获取name对应的列表的长度    
llen(self, name: _Key) -> int: ...
# 在指定值前面或后面插入值 
linsert( self, name: _Key, where: Literal["BEFORE", "AFTER", "before", "after"], refvalue: _Value, value: _Value) -> int: ...
# 对name对应的list中的某一个索引位置重新赋值
lset(self, name: _Key, index: int, value: _Value) -> bool: ...  
# 删除name对应的list中所指定的值,count指定删除多少
# count=0 全部删除, count=2 从前往后删2个, count=-2 从后往前删2个 
lrem(self, name: _Key, count: int, value: _Value) -> int: ...
# 在name对应的列表左侧弹出第一个元素 rpop: 从右侧
lpop(self, name): ...
# 在name对应的列表中根据索引获取列表元素
lindex(self, name: _Key, index: int) -> _StrType | None: ... 
# 在name对应的列表分片获取数据[前闭后闭区间]
lrange(self, name: _Key, start: int, end: int) ->list[_StrType]:
# 重点block,阻塞,可以写一个超时时间
# 将多个列表排列,按照从左到后去pop对应列表的元素 
# keys: redis的name集合
# timeout: 超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内的数据的时间(秒),0表示永远阻塞
# brpop: 与blpop相反,从右往左获取数据
blpop(self, keys: _Value | Iterable[_Value], timeout: Literal[0] = ...) -> tuple[_StrType, _StrType]: 
# 从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
brpoplpush(self, src, dst, timeout=...): ...  

重点掌握

lpush,lpop,blpop,lrange,llen

自定制分批取列表的数据

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
# 使用
for item in scan_list('test', 5):
    print(item)
            

python操作之Set操作

Set操作,Set集合就是不允许重复的列表

sadd(name,values)

name对应的集合中添加元素

scard(name)

获取name对应的集合中元素个数

sdiff(keys, *args)

在第一个name对应的集合中且不在其他name对应的集合的元素集合

sdiffstore(dest, keys, *args)

# 获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中

sinter(keys, *args)

# 获取多一个name对应集合的并集

sinterstore(dest, keys, *args)

# 获取多一个name对应集合的并集,再讲其加入到dest对应的集合中

sismember(name, value)

# 检查value是否是name对应的集合的成员

smembers(name)

# 获取name对应的集合的所有成员

smove(src, dst, value)

# 将某个成员从一个集合中移动到另外一个集合

spop(name)

# 从集合的右侧(尾部)移除一个成员,并将其返回

srandmember(name, numbers)

# 从name对应的集合中随机获取 numbers 个元素

srem(name, values)

# 在name对应的集合中删除某些值

srem(name, values)

# 在name对应的集合中删除某些值

sunion(keys, *args)

# 获取多一个name对应的集合的并集

sunionstore(dest,keys, *args)

# 获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中

sscan(name, cursor=0, match=None, count=None)
sscan_iter(name, match=None, count=None)

# 同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大

有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。

*zadd(name, *args, *kwargs)

# 在name对应的有序集合中添加元素
# 如:
     # zadd('zz', 'n1', 1, 'n2', 2)
     # 或
     # zadd('zz', n1=11, n2=22)

zcard(name)

# 获取name对应的有序集合元素的数量

zcount(name, min, max)

# 获取name对应的有序集合中分数 在 [min,max] 之间的个数

zincrby(name, value, amount)

# 自增name对应的有序集合的 name 对应的分数

r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)

# 按照索引范围获取name对应的有序集合的元素
 
# 参数:
    # name,redis的name
    # start,有序集合索引起始位置(非分数)
    # end,有序集合索引结束位置(非分数)
    # desc,排序规则,默认按照分数从小到大排序
    # withscores,是否获取元素的分数,默认只获取元素的值
    # score_cast_func,对分数进行数据转换的函数
 
# 更多:
    # 从大到小排序
    # zrevrange(name, start, end, withscores=False, score_cast_func=float)
 
    # 按照分数范围获取name对应的有序集合的元素
    # zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
    # 从大到小排序
    # zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)

zrank(name, value)

# 获取某个值在 name对应的有序集合中的排行(从 0 开始)
 
# 更多:
    # zrevrank(name, value),从大到小排序

zrangebylex(name, min, max, start=None, num=None)

# 当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的 值 (lexicographical ordering)来进行排序,而这个命令则可以返回给定的有序集合键 key 中, 元素的值介于 min 和 max 之间的成员
# 对集合中的每个成员进行逐个字节的对比(byte-by-byte compare), 并按照从低到高的顺序, 返回排序后的集合成员。 如果两个字符串有一部分内容是相同的话, 那么命令会认为较长的字符串比较短的字符串要大
 
# 参数:
    # name,redis的name
    # min,左区间(值)。 + 表示正无限; - 表示负无限; ( 表示开区间; [ 则表示闭区间
    # min,右区间(值)
    # start,对结果进行分片处理,索引位置
    # num,对结果进行分片处理,索引后面的num个元素
 
# 如:
    # ZADD myzset 0 aa 0 ba 0 ca 0 da 0 ea 0 fa 0 ga
    # r.zrangebylex('myzset', "-", "[ca") 结果为:['aa', 'ba', 'ca']
 
# 更多:
    # 从大到小排序
    # zrevrangebylex(name, max, min, start=None, num=None)

zrem(name, values)

# 删除name对应的有序集合中值是values的成员
 
# 如:zrem('zz', ['s1', 's2'])

zremrangebyrank(name, min, max)

# 根据排行范围删除

zremrangebyscore(name, min, max)

# 根据分数范围删除

zremrangebylex(name, min, max)

# 根据值返回删除

zscore(name, value)

# 获取name对应有序集合中 value 对应的分数

zinterstore(dest, keys, aggregate=None)

# 获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作
# aggregate的值为:  SUM  MIN  MAX

zunionstore(dest, keys, aggregate=None)

# 获取两个有序集合的并集,如果遇到相同值不同分数,则按照aggregate进行操作
# aggregate的值为:  SUM  MIN  MAX

zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
zscan_iter(name, match=None, count=None,score_cast_func=float)

# 同字符串相似,相较于字符串新增score_cast_func,用来对分数进行操作

redis的其他操作

delete(*names)

# 根据删除redis中的任意数据类型

exists(name)

# 检测redis的name是否存在

keys(pattern=’*’)

# 根据模型获取redis的name
 
# 更多:
    # KEYS * 匹配数据库中所有 key 。
    # KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
    # KEYS h*llo 匹配 hllo 和 heeeeello 等。
    # KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 

expire(name ,time)

# 为某个redis的某个name设置超时时间

rename(src, dst)

# 对redis的name重命名为

move(name, db))

# 将redis的某个值移动到指定的db下

randomkey()

# 随机获取一个redis的name(不删除)

type(name)

# 获取name对应值的类型

scan(cursor=0, match=None, count=None)
scan_iter(match=None, count=None)

# 同字符串操作,用于增量迭代获取key

管道

redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。

redis的事物也是基于这一特性而实现的

import redis
pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
conn = redis.Redis(connection_pool=pool)

pipe = conn.pipeline(transaction=True)
pipe.multi()
pipe.set('name', 'python')
pipe.set('role', 'tom')
pipe.execute()  # redis才开始去执行命令

Django中使用redis

方式1(通用方式):

utils文件夹下,建立redis_pool.py

import redis
POOL = redis.ConnectionPool(host='127.0.0.1',port=6379,password='1234',max_connections=1000)

然后在视图函数中使用

方式二:

安装django-redis模块

pip install django-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",
        }
    }
}

视图函数中使用:

1 使用cache
	from django.core.cache import cache
    cache.set('name',user) 
2 直接使用    
    from django_redis import get_redis_connection
    conn = get_redis_connection('default')
	print(conn.hgetall('xxx'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go&Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值