程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python operation redis from getting started to mastering attached code (all)

編輯:Python

Catalog

  • Preface
  • 1. Connect Redis
  • 2. Basic types
    • 2.1 String
    • 2.2 List
    • 2.3 Hash
    • 2.4 Set
    • 2.5 Zset
  • 3. actual combat
    • 3.1 Normal connection
    • 3.2 Connection pool connection

Preface

about Redis The corresponding principles and knowledge points of java edition , But look at my previous article :( Their knowledge points are interconnected )
Redis Framework from introduction to learning ( whole )

For the above pre knowledge, if you know better , If you don't understand , Think of it as a database , It's quick to get started .
In itself Redis Is a kind of durable Key-Value The database of , Rich data structures, etc

adopt pip install redis Perform installation import redis Module package of
If you encounter these problems during installation and use bug
But look at my previous article :

  1. Redis (error) NOAUTH Authentication required. resolvent
  2. Redis Could not connect to Redis at 127.0.0.1:6379: Connection refused resolvent
  3. linux Set in redis Password
  4. Redis appear Creating Server TCP listening socket *:6379: bind: No error Solutions for ( whole )

1. Connect Redis

It is a kind of database , The first step in database operation is to connect Redis, There are two classes that can connect , The official provided Redis(StrictRedis Subclasses of ) as well as StrictRedis.

There are also two ways to connect :

The first way is to connect normally :

# Import redis My bag 
import redis
# adopt redis Connection user name 、 port 、 Password and db database 
redis_conn = redis.Redis(host='127.0.0.1', port= 6379, password= '?', db= 0,decode_responses=True)
redis_conn = redis.StrictRedis(host='127.0.0.1', port= 6379, password= '?', db= 0,decode_responses=True)

About the above connection parameters :
decode_responses=True When output, it becomes a string , The default output is bytes (decode_responses It's not necessary )

The second way to connect is :( Use connection pool )
The advantage of connection pooling is that it manages all its connections through connection pooling , Avoid the overhead of establishing and releasing connections

import redis
redis_pool = redis.ConnectionPool(host='127.0.0.1', port= 6379, password= '?', db= 0)
# By calling connection pool 
redis_conn = redis.Redis(connection_pool= redis_pool)

2. Basic types

Introduce the use of its methods in the basic types
After normal connection Most of them can be viewed as having something in common as follows :
adopt set Set key value pairs :redis.set('manong',18)
Get key value :redis.get('manong')
Determine whether the key value exists :redis.exists('manong')
View the type of key value :redis.type('manong')
Get the number of key value pairs in the current database :redis.dbsize()
And other functions , You can learn from the official website

Basic usage types and methods can be used

2.1 String

Actually Sting Class has been used in the above presentation

function :

describe The usage function Set a single key value pair set(name, value, ex=None, px=None, nx=False, xx=False, keepttl=False, get=False, exat=None, pxat=None) If key If it does not exist, it will be added successfully setnx(name, value) Set up key The expiration time of setex(name, time, value) In seconds ,psetex(name, time_ms, value) In Milliseconds Get a single key value pair get(name) Set multiple key value pairs mset(*args, **kwargs) Get multiple key value pairs mget(keys, *args) Value does not exist set new key value pair getset(name, value) Modify values according to index setrange(name, offset, value) Get the value according to the index getrange(key, start, end) Add value according to the built value append(key, value) Get value length strlen(name)

String Another characteristic is : Auto increment type can be set ( Different types set different types of auto increment , Pay attention to distinguish between )

  • incr(name, amount=1)
  • incrbyfloat(name, amount=1.0)

The usage of the above functions is as follows :
Usage of single key value pairs

r.set("name", " Code farmer research monk ")
r.get("name")
r.append("name", " Big brother ") # key After adding , If it does not exist, it will not succeed 
""" about set There are many parameters for , Different parameters and different delays """
r.setex("name", 10086, " Code farmer research monk ") # 10086 Seconds after expired 
# similar 
r.set("name", " Code farmer research monk ", ex = 10086)
r.psetex("name", 10086, " Code farmer research monk ") # 10086 Expired in milliseconds 
# similar 
r.set("name"," Code farmer research monk ",px = 10086)
r.setnx("name", " Code farmer research monk ") # key No, set successfully , That is to say newly build Key value 
# similar 
r.set("name", " Code farmer research monk ",nx=True)
r.setxx("name", " Code farmer research monk ") # key Existence set successfully , That is to say modify Key value 
# similar 
r.set("name", " Code farmer research monk ",xx=True)

Usage of multiple key value pairs :

r.mset({
'k1': 'v1', 'k2': 'v2'}) # Set multiple values , Pass in the dictionary 
r.mget("k1", "k2") # Return a list , Take out multiple values at once 
r.getset("name", " Pay attention to me ") # Set new value , And return the previous value 
# similar 
dict = {

'k1' : 'v1',
'k2' : 'v2'
}
r.mset(dict)

Scope and the use of autoincrement :

r.setrange("name", 2, " Development ") # From 2 Start the replacement at the next position (0 Starting number ), It turned out that it was the code farmer research monk , After the replacement, it is the code agriculture development 
r.getrange("name", 2, 3) # Take the middle substring , For development 
r.strlen("name") # length , There is no such thing as 0
r.incr("name", amount=3) # With 3 Is self increasing , If it doesn't exist, it will take 3 For the initial value , Don't specify amount The default is 1
r.incrbyfloat("name", amount=0.3) # With 0.3 Self increasing , Empathy 
r.decr("name", amount=3) # The same goes for diminishing 
r.delete("name1") # Delete 

2.2 List

describe The usage function lpush(name,values) Corresponding name Add... From center to left list Elements rpush(name,values) Corresponding name Add... From the middle to the right list Elements lpushx(name, value) Past existence name Add the left element to the list of , No cannot create rpushx(name, value) Past existence name Add the left element to the list of , No cannot create linsert(name, where, refvalue, value)) adopt refvalue Of where( Sure before perhaps after) Insert valuer.lset(name, index, value) Modify the corresponding list An index value in the list r.lrem(name, num, value) Delete list List specified values lpop(name) Delete the first element on the left of the list , Return deleted elements rpop(name) Delete the first element to the right of the list , Return deleted elements ltrim(name, start, end) Delete values outside the index lindex(name, index) Get the list value according to the index rpoplpush(list1,anotherlist1)list1 Insert the rightmost value in the list of anotherlist1 On the far left of the list brpoplpush(list1,anotherlist1, timeout=0)list1 The leftmost value in the list is inserted anotherlist1 To the far right of the list blpop(keys, timeout) Remove multiple lists at once

Insert the specific usage of the element :

r.lpush("list1", 1,2,3) # Insert... From the left , adopt r.lrange('list1',0,2) obtain 321.list1 Does not exist, will create 
r.rpush("list2", 1,2,3) # Insert... From the right , adopt r.lrange('list2',0,2) obtain 123
r.lpushx("list1", 4,5) # Insert... From the left , adopt r.lrange('list1',0,5) obtain 45321
r.rpushx("list1", 4,5) # Insert... From the right , adopt r.lrange('list1',0,6) obtain 453216

Other indicators of addition, deletion, modification and query :( View the last value , adopt r.lrange('list4',0,-1) ).
python There are many output formats for : Through the following format Format print("list4:{}".format(r.lrange('list4',0,-1)))

r.lrange("list1",0,-1) # The default is to output all values , Return to all lists 
r.llen("list1") # Number of return elements 
r.lindex("list1", 1) # By subscript 1 The value of 
r.linsert("list1", "before", 5,3) # 5 Insert before 3, The value itself is 453216, Finally 4353216
r.lset("list1", 2, 6) # Amendment No 2 Elements are 6, The final value is 456216
r.rpush("list4", 2,2,1,2,3,4,5,6,1,1) # Insert... From the right , adopt r.lrange('list4',0,-1) obtain 1212345611
r.lrem("list4", 1, 2) # Delete the first one on the left 2
r.lrem("list4", -1, 1) # Delete the first one on the right 1, Negative numbers are from back to front 
r.lrem("list4", 0, 1) # Delete all 1
r.lpop("list4") # Delete the first value on the left and return the deleted value 
r.rpop("list4") # Delete the first value on the right and return the deleted value 
r.ltrim("list4", 2, 3) # Except subscript 2 To 3 The elements of , Everything else has been deleted 

2.3 Hash

describe The usage function hset(name, key, value) Set key value pairs . Modify as you have and create as you do not hget(name, key) Take out a single key Value hmget(name, key,…) Take out multiple key Value hgetall(name) Take out all corresponding key value pairs hkeys(name) Take out all keyhvals(name) Take out all valuehlen(name) Get the number of key value pairs hexists(name, key) See if this... Exists key

Self increasing and piecewise functions
Mainly to prevent multiple values , Burst memory
Specific ideas are passed through

  1. adopt cursor Get data at the flag location of
  2. match Parameter filtering , If specified None For all key, If specified key Then filter key come out
  3. count At least key The number of , by None Is the number of default partitions

It is commonly used in application scenarios , So put it in a separate table :

describe The usage function hincrby(name, key, amount=?) Yes key Self increasing positive or negative hincrbyfloat(name, key, amount=?.0) Yes key Self incrementing positive floating point number or negative floating point number hscan(name, cursor=0, match=None, count=None) Specify the cursor to get data hscan_iter(name, match=None, count=None) ditto , Just encapsulate it in an iterator

The specific operation is as follows :

r.hset("names", "manong", "yanjiuseng") # Set key value pairs 
r.hmset("names", {
"manong": "yanjiuseng", ....}) # Set multiple key value pairs ,redis4.0 Before version 
r.hset("names", mapping={
"manong": "yanjiuseng", ...}) # Set multiple key value pairs ,redis4.0 After version 
r.hget("names", "manong") # Take out key Corresponding value value , Back to its value value 
r.hmget("names", ["manong", "age"]) # Take out multiple key Corresponding value value , Back to its value value 
r.hgetall("names") # Take out multiple key value pairs ( Dictionaries )
r.hkeys("names") # Remove all key( list )
r.hvals("names") # Remove all value( list )
hlen("names") # Get the number of key value pairs 
r.hexists("names", "ma") # See if this... Exists key
r.hincrby("names", "age", amount=1)
# Self increasing 1,age This is not set , with amount For the initial , It can also be negative 

Specific operation of fragment reading :

cursor1, data1 = r.hscan('names', cursor=0, match=None, count=None)
cursor2, data2 = r.hscan('names', cursor=cursor1, match=None, count=None)
r.hscan_iter("names", match=None, count=None) # Remove all key, Notice that we use traversal , Traverse its value 
# As follows 
for item in r.hscan_iter('xx'):
print item

2.4 Set

set The element itself is unordered and unrepeatable

describe The usage function sadd(name,values) Add one or more elements to the collection sismember(name, value) Judgment set name Is there a corresponding in value Elements , return false perhaps truesmove(src, dst, value) take src In the collection value Element moved to dst Collection sdiff(keys, *args) Returns that only the first set exists names in , After that names Sets are excluded ( Difference set )sdiffstore(dest, keys, *args) There is only the second set of names, After that names Sets are excluded , Put it first dest Collection sinter(keys, *args) Multiple sets names intersect sinterstore(dest, keys, *args) Multiple names intersect , Store in the first dest Collection sunion(keys, *args) Multiple sets names Union and collection sunionstore(dest,keys, *args) Multiple sets names Union and collection , Store in the first dest Collection spop(name) Delete elements randomly , And return the output of this element srem(name, values) Deletes the specified in the collection value value , And return the number of deleted elements

Add new elements and query :

r.sadd("names", "ma", "nong", "yan", "jiu", "seng") # Returns the number of set lengths 5
r.sismember("names", "ma") # Inquire about ma Whether elements exist , return false perhaps true operation 
r.scard("names") # Get the number of set elements 
# When supplementing the test output , It can be done by :
print(' Number of collection elements :{}'.format(r.scard("names")))
r.smembers("names") # Returns all collection elements 
r.sscan('names') # Returns all elements of the collection ( Display in the form of Yuanzu )
r.scan_iter("names") # Returns all elements of the collection ( You need to output through traversal )
# for example 
for i in r.sscan_iter("names"):
print(i)

Operation of difference set :

r.sdiff("names1", "names2") # Return existence names1 non-existent names2 Collection elements for 
r.sdiffstore("names3", "names1", "names2") # There is names1 non-existent names2 Collection elements for , Store in names3 in , And output this set 

The operation of intersection :

r.sinter("names1", "names2") # return names1 and names2 The intersection elements of 
r.sinterstore("names3", "names", "names2") # hold names and names2 The intersection of is saved to names3, return names3 The elements of 

Union operation :

r.sunion("names1", "names2") # return names1 and names2 Union element of 
r.sunionstore("names3", "names1", "names2") # hold names and names2 Save union of to names3, return names3 The elements of 

Operation of difference set :

r.spop("names") # Randomly delete an element , And return this element to the output 
r.srem("names", "ma") # Deletes the specified element ma, Returns the number of deleted items 

2.5 Zset

This zset And set The difference is that
zset For an orderly collection , Will sort the elements

describe The usage function zadd(name, {‘k1’:v1,‘k2’:v2}) Add elements to an ordered set zcard(name) Get the number of ordered collection elements r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float) Get the elements of an ordered collection .desc For collation , The default is value Sort from small to large .withscores Whether to obtain value, Do not get by default value Only key.score_cast_func Yes value The function to convert zrevrange(name, start, end, withscores=False, score_cast_func=float) ditto , Only the collection is sorted from large to small by default zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float) Corresponding value Value to get its corresponding key as well as value Elements , Default value From small to large zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float) ditto , It's just value The default is from large to small zscan(name, cursor=0, match=None, count=None, score_cast_func=float) Get all value, Default value From small to large zcount(name, min, max) Statistics value stay min as well as max Number of elements of zincrby(name, amount, value) Corresponding name In the collection of value fraction , It increases every time amountzrank(name, value) Get collection name Medium value What's the number , Export the index number in positive order from small to large zrevrank(name, value) ditto , It's just a positive index number from big to small zscore(name, key) Get collection name in key Corresponding value value zrem(name, key) Delete the collection name In a single key value zremrangebyrank(name, min, max) Delete the corresponding index element ( Put it value Sort from small to large )zremrangebyscore(name, min, max) Delete value The scope is min as well as max Between ( Put it value Sort from small to large )

Fetch element key And corresponding value, Specific operation :

r.zadd("names", {
"ma": 1, "nong": 2, "yan": 3}) # New elements , And set the corresponding key as well as value
r.zcard("names") # Returns the number and length of an ordered set 
r.zrange("names", 0, -1) # Take out the assembly names Of all elements in key
r.zrange("names", 0, -1, withscores=True) # Take out the assembly names All elements in positive sequence Sort , Yes key as well as value
r.zrevrange("names", 0, -1, withscores=True) # ditto , Reverse order operation 
r.zrangebyscore("names", 1, 3, withscores=True) # Extract from the set value The scope is 1-3 Between ,value Output the corresponding... From small to large key as well as value
r.zrevrangebyscore("names", 1, 3, withscores=True) # ditto , Output from large to small 
r.zscan("names") # Take out all the elements of the ordered set 
r.zscan_iter("names") # Get all the elements , This is an iterator 
# The specific operation is as follows :
for i in r.zscan_iter("names"): # Ergodic iterator 
print(i)

Count 、 Self increasing 、 Get the index and delete :

r.zcount("names", 1, 3) # Statistics value stay 1-3 The number of elements between , And back to 
r.zincrby("names", 2, "ma") # take ma Of value Self increasing 2
r.zscore("names", "ma") # return key Corresponding value
r.zrank("names", "ma") # Returns the element ma The subscript ( Sort from small to large )
r.zrerank("names", "ma") # Returns the element ma The subscript ( Sort from large to small )
r.zrem("names", "ma") # Removing a single key
r.zremrangebyrank("names", 0, 2) # Delete subscript in 0 To 2 The elements between 
r.zremrangebyscore("names", 1, 3) # Delete value stay 1-3 Between the elements 

3. actual combat

combination python web Development
Get through the form redis The data of
Connect through normal connection or connection pool
After the connection is successful, you can get the desired data and transfer it back to the form

3.1 Normal connection

Call the general redis function , Or encapsulate a connection function

def get_redis(config):
sentinels = config.get("sentinels", "")
cluster_tag = config.get("cluster_tag", "")
if all([sentinels, cluster_tag]):
sentinel = Sentinel(sentinels, socket_timeout=5)
REDIS = sentinel.master_for(cluster_tag, socket_timeout=5)
else:
REDIS = StrictRedis(host=config.get("host", "127.0.0.1"),
port=config.get("port", 6379))
return REDIS

3.2 Connection pool connection

General enterprises have very clear assembly lines
If divided dev And the production environment , Different redis The cluster configuration is different
This part is setting The public configuration of

REDIS_CACHES = {

'manongyanjiuseng': {

'type': 'sentinel',
'cluster_tag': 'manongyanjiuseng_test',
'host': [
("ip", Port number ),
("https://blog.csdn.net/weixin_47872288", Port number ),
("https://blog.csdn.net/weixin_47872288", Port number ),
],
'socket_timeout': 10,
'master': 1,
'db': 3
},
# In the same way, create as above 
}

The functions of public classes are placed in common.py in

import redis
from redis.sentinel import Sentinel
from redis import StrictRedis
# Initialize a thread pool 
CONNECTION_POOL = {
}
# Define the parameters of the connection 
def get_redis_connection(server_name='default'):
# Variables inside the function can be changed outside the function , So define global
global CONNECTION_POOL
if not CONNECTION_POOL:
CONNECTION_POOL = _setup_redis()
pool = CONNECTION_POOL[server_name]
if settings.REDIS_CACHES[server_name].get("type") == "sentinel":
return pool
return redis.Redis(connection_pool=pool)
def _setup_redis():
for name, config in settings.REDIS_CACHES.items():
if config.get("type") == "sentinel":
sentinel = Sentinel(config['host'], socket_timeout=config['socket_timeout'])
if config.get('master'):
pool = sentinel.master_for(
config["cluster_tag"],
redis_class=redis.Redis,
socket_timeout=config['socket_timeout']
)
else:
pool = sentinel.slave_for(
config["cluster_tag"],
redis_class=redis.Redis,
socket_timeout=config['socket_timeout']
)
else:
pool = redis.ConnectionPool(
host=config['host'],
port=config['port'],
db=config['db'],
socket_timeout=1
)
CONNECTION_POOL[name] = pool
return CONNECTION_POOL

When calling the connection, you can use the following :

# manong This value is determined by form The form is passed in 
redis = get_redis_connection(manong)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved