使用python對redis操作

寫在前面

首先聲明,這是爲了學習python對redis操作而寫的一個小demo,包括了這幾天網站找到的一些資料,綜合總結出來一些東西,最後附上我寫的一個用python操作redis的一個demo:

模塊安裝

python提供了一個模塊redis-py來使我們很方便的操作redis數據庫,安裝該模塊也很簡單,直接使用pip安裝就行,命令如下:

pip install redis

安裝完之後,使用import調用一下就能知道是否安裝成功,在python界面下輸入import redis,如果不報錯,那麼該模塊就算安裝成功了。

模塊安裝成功後,就可以創建redis連接了,接下來學習怎樣創建redis連接:

redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令(比如,SET命令對應與StrictRedis.set方法)。Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。 簡單說,官方推薦使用StrictRedis方法。

這裏不推薦使用Redis類,原因是他和咱們在redis-cli操作有些不一樣,主要不一樣是下面這三個方面。 

    (1)LREM:參數 ‘num’ 和 ‘value’ 的順序交換了一下,cli是 lrem queueName 0 ‘string’ 。這裏的0是所有的意思。 但是Redis這個類,把控制和string調換了。 

    (2)ZADD:實現時 score 和 value 的順序不小心弄反了,後來有人用了,就這樣了

    (3)SETEX: time 和 value 的順序反了

我們可以使用StrictRedis直接連接redis,代碼如下:

#創建一個redis連接
r=redis.StrictRedis(host='192.168.7.25',port=6379,db=0)

連接池的使用

但是,對於大量redis連接來說,如果使用直接連接redis的方式的話,將會造成大量的TCP的重複連接,所以,推薦用連接池來解決這個問題,使用連接池連接上redis之後,可以從該連接池裏面生成連接,調用完成之後,該鏈接將會返還給連接池,供其他連接請求調用,這樣將減少大量redis連接的執行時間,下面介紹兩個類Redis和StrictRedis的連接池的實現方式:

Redis的連接池的方法:
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
StrictRedis的連接池的實現方式:
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, db=0)
r = redis.StrictRedis(connection_pool=pool)
官方提供的redis連接池可以添加的參數: 
class redis.StrictRedis(host='localhost', port=6379, db=0, password=None, socket_timeout=None, connection_pool=None, charset='utf-8', errors='strict', decode_responses=False, unix_socket_path=None)
Implementation of the Redis protocol.This abstract class provides a Python interface to all Redis commands and an implementation of the Redis protocol.
Connection and Pipeline derive from this, implementing how the commands are sent and received to the Redis server

一些小demo

接下來,需要提出redis的幾種數據類型了,我使用redis客戶端連接redis的時候,發現redis支持五種數據類型的key,列表如下:

string:存儲string,以及int或者float等數據類型的數據。

list:存儲列表類型的數據

hash:存儲字典類型的數據

set:存儲集合類型的數據

zset:存儲的也是集合類型的數據,不過數據是有序存儲的(該類型目前demo裏面沒有加入。。。)

好了,瞭解了redis支持的數據類型之後,就可以寫一些小demo了,下面是一些小demo:

#創建一個string類型的key並放入value
r.set("abc",34634)
#創建一個hash
r.hset('abc:def', 'name', "abcde")
#獲取一個hash的所有值
print r.hgetall('abc:def')
#獲取一個hash的所有key
print r.hkeys('abc:def')    
#創建list
r.sadd('abcd:ef','nihao')
r.sadd('abcd:ef','hello')
r.sadd('xxxx','nihao')
r.sadd('xxxx','good')
#打印出該key中的值 list
print r.smembers('abcd:ef')
#查詢兩個list中相同的值
print r.sinter('abcd:ef', 'xxxx')
#給兩個list取並集
print r.sunion('abcd:ef', 'xxxx')
#列出所有key
print r.keys()
#列出以abc開頭的所有key
print r.keys("abc*")

demo總結

由於之前公司碰到過需求,需要批量修改一批key的value,之前使用shell也可以做,不過,現在就通過完成這個需求使用python來實現這個小demo吧。

該demo中將會附上我的一些解釋,希望各路大神不要吐槽。。。很久沒動手寫python了,再寫就是各種蛋疼。。。。。。

#!/usr/bin/env python
#coding=utf-8
import redis    #導入redis-py模塊
class RedisPool:    #定義了一個連接池類,該類返回連接池中的一個連接給調用者
    def Redis_Pool(self,ClientHost="192.168.0.25",ClientPort=6379,ClientDb=0):
        pool=redis.ConnectionPool(host=ClientHost,port=ClientPort,db=ClientDb)
        return redis.StrictRedis(connection_pool=pool)
class ChangeKey: #該類使用獲取到的redis連接對想要進行修改的key進行修改
    
    def Change_String(self,R,Key,Value):  
        try:
            Bool = R.set(Key,Value)
        except Exception as e:
            Bool = False
            print 'Insert string Error:',e
        return Bool
    
    def Change_List(self,R,KeyName,Key):
        Filed_List=[]
        for i in range(0,len(Key)):
            try:
                R.rpush(KeyName,Key[i])
            except Exception as e:
                Filed_List.append((KeyName,Key[i]))
                print 'Insert set Error:',e
        return Filed_List
    
    def Change_Hash(self,R,KeyName,Key):
        Filed_List=[]
        for i in Key.keys():
            try:
                R.hset(KeyName,i,Key[i])
            except Exception as e:
                Filed_List.append([i,Key[i]])
                print 'Insert set Error:',e
        return Filed_List
    
    def Change_Set(self,R,KeyName,Key):
        Filed_List=[]
        NewKey=list(Key)
        for i in range(0,len(NewKey)):
            try:       
                R.sadd(KeyName,NewKey[i])
            except Exception as e:
                Filed_List.append(KeyName,NewKey[i])
                print 'Insert set Error:',e
        return Filed_List
    
    def Change_Key(self,R,Keys):    #通過傳遞進來的Keys判斷其值是屬於哪種類型,從而調用不同的key的插入函數將該key插入進redis中
        for i in Keys:
            if isinstance(Keys[i],(str,int,float,long)):
                print "The key %s type is string,will input new value:" %(i)
                Bool = self.Change_String(R,i,Keys[i])
                if Bool:
                    print "Update is ok,the key:%s New value:%s" %(i,Keys[i])
                else:
                    print "Update is Filed,the Filed key %s value %s" %(i,Keys[i])    
            elif isinstance(Keys[i],list):
                print "The key %s type is list,will input new value:" %(str(i))
                Filed_List = self.Change_List(R,i,Keys[i])
                if len(Filed_List) == 0:
                    print "Update is ok,the key:%s New value:%s" %(i,Keys[i])
                else:
                    print "Update is Filed,the Filed List is %s" %(Filed_List)
            elif isinstance(Keys[i],dict):
                print "The key %s type is hash,will input new value:" %(str(i))
                Filed_List = self.Change_Hash(R,i,Keys[i])
                if len(Filed_List) == 0:
                    print "Update is ok,the key:%s New value:%s" %(i,Keys[i])
                else:
                    print "Update is Filed,the Filed List is %s" %(Filed_List)
            elif isinstance(Keys[i],set):
                print "The key %s type is set,will input new value:" %(str(i))
                Filed_List = self.Change_Set(R,i,Keys[i])
                if len(Filed_List) == 0:
                    print "Update is ok,the key:%s New value:%s" %(i,Keys[i])
                else:
                    print "Update is Filed,the Filed List is %s" %(Filed_List)
            else:
                print "The Key %s not match that support type.The support type:string,list,hash,set." %(i)
class BatchChangeKey:
    def Batch_Change_Key(self,R,Keys,Value):
        for i in R.keys(Keys):
            self.ChangeKey=ChangeKey()
            self.ChangeKey.Change_Key(R,{i:Value})
    
 
def main():
      Pool=RedisPool()    #調用連接池類
      R=Pool.Redis_Pool("192.168.0.25",6379,0)    #獲取該連接池中的一個連接
    #keys={'m':'huxianglin','e':[1,2,3],'c':{'z':'a','c':'b'},"abc:def:ghi":set(["a","b","c"])}
      #changekey=ChangeKey()    #使用上面定義的Keys傳遞給該類,傳遞的keys要求是一個字典類型的數據
      #changekey.Change_Key(R,keys)
    batchchangekey=BatchChangeKey()    #調用批量修改的類,並將需要批量修改的key的一部分傳遞進去,可以通過R.keys(key)獲取到能匹配的key的list,再遍歷這個列表,將value傳遞進去
    batchchangekey.Batch_Change_Key(R,"abc:defg:*" , "helloworld")
if __name__ == '__main__':
    main()


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章