【2022-11-15】luffy项目实战(八)

一、Redis字符串操作

# Redis字符串操作

'''
1 set(name, value, ex=None, px=None, nx=False, xx=False)
2 setnx(name, value)
3 psetex(name, time_ms, value)
4 mset(*args, **kwargs)
4 get(name)
5 mget(keys, *args)
6 getset(name, value)
7 getrange(key, start, end)
8 setrange(name, offset, value)
9 setbit(name, offset, value)
10 getbit(name, offset)
11 bitcount(key, start=None, end=None)
12 strlen(name)
13 incr(self, name, amount=1)
14 incrbyfloat(self, name, amount=1.0)
15 decr(self, name, amount=1)
16 append(key, value)
'''

Redis_str.py

import redis

connent = redis.Redis()

1. set(name, value, ex=None, px=None, nx=False, xx=False)
connent.set('name', 'jason')  # Redis使用key-value形式存储数据,value只能是字符串或字节格式
connent.set('name', 'tony', ex=5)  # ex,过期时间(秒)到3s过期,数据就没了
connent.set('name', 'kevin', px=5000)  # px,过期时间(毫秒)到3s过期,数据就没了
connent.set('age', '23', nx=True)   # nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
connent.set('hobby', '篮球', xx=False)  # xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值

2. setnx(name, value)
connent.setnx('Game', 'LoL')    #  设置值,只有name不存在时,执行设置操作(添加),如果存在,不会修改

3. psetex(name, time_ms, value)
connent.psetex('name', 3000, 'jason')     # time_ms,过期时间(数字毫秒 或 timedelta对象

4. mset(*args, **kwargs)
connent.mset({'name': 'tony', 'age': '18'})  #  字典批量传值

5. get(name)
print(connent.get('name'))
print(str(connent.get('name'), encoding='utf-8'))  # 获取数据值,取到的是bytes格式,指定:decode_responses=True,完成转换

6. mget(keys, *args)
info = connent.mget(['name', 'age', 'hobby'])  # 批量获取数据值
print(info)

7. getset(name, value)
info = connent.getset('name', 'jason')  # 设置新值并获取原来的值
print(info)

8. getrange(key, start, end)
info = connent.getrange('name', 0, 1)   # 取的是字节,前闭后闭区间
print(info)

9. setrange(name, offset, value)
connent.setrange('name', 1, 'tony')  # 从某个起始位置开始替换字符串

10. setbit(name, offset, value)
connent.setbit('name', 1, 0)        # 对name对应值的二进制表示的位进行操作
info = connent.get('name')
print(info)

11. getbit(name, offset)
info = connent.getbit('name', 1)    # 获取name对应的值的二进制表示中的某位的值 (0或1)
print(info)

12. bitcount(key, start=None, end=None)
print(connent.bitcount('name', 0, 2))   # 获取name对应的值的二进制表示中 1 的个数

13. strlen(name)
print(connent.strlen('name'))   # 返回name对应值的字节长度(一个汉字3个字节)

14. incr(self, name, amount=1)
connent.incr('age', amount=1)  # 自增name对应的值,当name不存在时,则创建name=amount,否则,则自增

15. incrbyfloat(self, name, amount=1.0)
connent.incr('age', amount=1)  # 自增name对应的值,当name不存在时,则创建name=amount,否则,则自增

16. decr(self, name, amount=1)
connent.decr('age')   		  # 自减name对应的值,当name不存在时,则创建name=amount,否则,则自减

17. append(key, value)
connent.append('name', 'nb')  # 在redis name对应的值后面追加内容

# 关闭连接
connent.close()

二、Redis hash操作

Redis_hash.py

# Redis hash操作

'''
1 hset(name, key, value)
2 hmset(name, mapping)
3 hget(name,key)
4 hmget(name, keys, *args)
5 hgetall(name)
6 hlen(name)
7 hkeys(name)
8 hvals(name)
9 hexists(name, key)
10 hdel(name,*keys)
11 hincrby(name, key, amount=1)
12 hincrbyfloat(name, key, amount=1.0)
13 hscan(name, cursor=0, match=None, count=None)
14 hscan_iter(name, match=None, count=None)
'''
import redis

connent = redis.Redis()

1. hset(name, key, value)   #  name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
connent.hset('userinfo', 'name', 'xxx')
connent.hset('userinfo', 'age', '18')

2. hmset(name, mapping)   # 在name对应的hash中批量设置键值对
connent.hmset('xx', {'k1':'v1', 'k2': 'v2'})

3. hget(name,key)  # 在name对应的hash中获取根据key获取value
info = connent.hget('userinfo','age')
print(info)

4. hmget(name, keys, *args)  # 在name对应的hash中获取多个key的值
info = conn.hmget('userinfo',['name','age'])
print(info)

5. hgetall(name)  # 获取name对应hash的所有键值
info = conn.hgetall('userinfo')
print(info)

6. hlen(name)  # 获取name对应的hash中键值对的个数
info = conn.hlen('userinfo')
print(info)

7. hkeys(name)  # 获取name对应的hash中所有的key的值
info = conn.hkeys('userinfo')
print(info)

8. hvals(name)  # 获取name对应的hash中所有的value的值
info = conn.hvals('userinfo')
print(info)

9. hexists(name, key)  # 检查name对应的hash是否存在当前传入的key
info = conn.hvals('userinfo', 'name')
print(info)

10. hdel(name,*keys)  # 将name对应的hash中指定key的键值对删除
connent.hdel('userinfo','age')

11. hincrby(name, key, amount=1)  # 自增name对应的hash中的指定key的值,不存在则创建key=amount
connent.hincrby('userinfo','age')  

12. hincrbyfloat(name, key, amount=1.0)  # 自增name对应的hash中的指定key的值,不存在则创建key=amount
connent.hincrbyfloat('userinfo','age') 

13. hscan(name, cursor=0, match=None, count=None)  # 增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆
for i in range(100):
	connent.hset('test_hash','key_%s'%i,'技师%s号'%i)
    
14. hscan_iter(name, match=None, count=None)  # 利用yield封装hscan创建生成器,实现分批去redis中获取数据
info = connent.hscan_iter('test_hash',count=100)
print(info)  # 生成器
for item in info:
    print(item)
    
# 关闭连接
connent.close()

三、Redis列表操作

Redis_list.py

# Redis列表操作

'''
1 lpush(name,values)
2 lpushx(name,value)
3 rpushx(name, value) 表示从右向左操作
4 llen(name)
5 linsert(name, where, refvalue, value))
6 lset(name, index, value)
7 lrem(name, value, num)
8 lpop(name)
9 lindex(name, index)
10 lrange(name, start, end)
11 ltrim(name, start, end)
12 rpoplpush(src, dst)
13 blpop(keys, timeout)
14 brpoplpush(src, dst, timeout=0)
15 自定义增量迭代
'''
import redis

connent = redis.Redis()

1. lpush(name,values)  # 在name对应的list中添加元素,每个新的元素都添加到列表的最左边
connent.lpush('xx', 11,22,33)

2. lpushx(name,value)  # 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
connent.rpush('xx', 44)

3. rpushx(name, value)
connent.lpushx('yy', 55)  # 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边

4. llen(name)
info = connent.llen('xx')  # name对应的list元素的个数
print(info)

5. linsert(name, where, refvalue, value)
connent.linsert('xx', where='after', refvalue='22', value='66')  # 在name对应的列表的某一个值前或后插入一个新值
connent.linsert('xx', where='before', refvalue='22', value='66')

6. lset(name, index, value)
connent.lset('xx', 0, '77')  # 对name对应的list中的某一个索引位置重新赋值

7. lrem(name, value, num)
connent.lrem('xx', 1, '66')  # 在name对应的list中删除指定的值

8. lpop(name)
info = connent.lpop('yy', count=1)  # 在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
info1 = connent.rpop('yy', count=1)  # 在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
print(info)
print(info1)

9. lindex(name, index)
connent.lindex('xx', 0)  # 在name对应的列表中根据索引获取列表元素

10. lrange(name, start, end)
connent.lrange('xx', 0, 2)  # 在name对应的列表分片获取数据

11. ltrim(name, start, end)
info = connent.ltrim('xx', 1, 3)  # 在name对应的列表中移除没有在start-end索引之间的值
print(info)

12. rpoplpush(src, dst)
connent.rpoplpush('xx', 'yy')  # 从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边

13. blpop(keys, timeout)
info = connent.blpop('yy')  # 阻塞式弹出,如果列表中有值,会造成阻塞,直到有值,它可以做消息对了,将多个列表排列,按照从左到右去pop对应列表的元素
print(info)

14. brpoplpush(src, dst, timeout=0)
info = connent.brpoplpush('yy', timeout=3)  # 从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
print(info)

15. 自定义增量迭代
info = connent.lrange('yy', 0, 999)
# 由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要:
# 1、获取name对应的所有列表
# 2、循环列表
print(info)


# 关闭连接
connent.close()
# 自定义生成器

import redis
conn = redis.Redis(host='127.0.0.1', port=6379)
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)

四、Redis管道操作

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

redis事务机制可以保证一致性和隔离性,无法保证持久性,但是对于redis而言,本身是内存数据库,所以持久化不是必须属性。原子性需要自己进行检查,尽可能保证

它不像mysql一样,支持强事务,事务的四大特性不能全部满足,但是能满足一部分,通过redis的管道实现的,redis本身不支持事务,但是可以通过管道,实现部分事务

redis 通过管道,来保证命令要么都成功,要么都失败,完成事务的一致性,但是管道只能用在单实例,集群环境中,不支持pipline
import redis

connent = redis.Redis()
pipline = connent.pipeline(transaction=True)
pipline.decr('x', 2)  # x减2
raise Exception('无法接收')
pipline.incr('y', 2)  # y加2
pipline.execute()

# 关闭连接
conn.close()

五、Redis其他操作

# 通用操作:无论是5大类型的那种,都支持

import redis

connent = redis.Redis()

1. delete(*names)  # 根据删除redis中的任意数据类型
conn.delete('age', 'name')

2. exists(name)  # 检测redis的name是否存在
info=conn.exists('xx')
print(info)  # 0


3. keys(pattern='*')  # 根据模型获取redis的name
info=conn.keys('*o*')
info=conn.keys('?o*')
print(info)

4. expire(name ,time)  # 为某个redis的某个name设置超时时间
connent.expire('test_hash',3)

5. rename(src, dst)  # 对redis的name重命名
connent.rename('xx','xxx')


6. move(name, db)  # 将redis的某个值移动到指定的db下
# 默认操作都是0 库,总共默认有16个库
connent.move('xxx',2)


7. randomkey()  # 随机获取一个redis的name(不删除)
info = connent.randomkey()
print(info)

8. type(name)  # 获取name对应值的类型
info = conn.type('aa') 
print(info)

# 关闭连接
connent.close()

六、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模块

pip3 install django-redis

# setting里配置:
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'))

方式三

# 方式三:借助于django的缓存使用redis
    如果配置文件中配置了 CACHES  ,以后django的缓存,数据直接放在redis中
    以后直接使用cache.set 设置值,可以传过期时间
    使用cache.get 获取值
    强大之处在于,可以直接缓存任意的python对象,底层使用pickle实现的
posted @ 2022-11-15 20:57  dy12138  阅读(52)  评论(0)    收藏  举报