寫在前面python
首先聲明,這是爲了學習python對redis操做而寫的一個小demo,包括了這幾天網站找到的一些資料,綜合總結出來一些東西,最後附上我寫的一個用python操做redis的一個demo:
redis
模塊安裝shell
python提供了一個模塊redis-py來使咱們很方便的操做redis數據庫,安裝該模塊也很簡單,直接使用pip安裝就行,命令以下:數據庫
pip install redis
安裝完以後,使用import調用一下就能知道是否安裝成功,在python界面下輸入import redis,若是不報錯,那麼該模塊就算安裝成功了。app
模塊安裝成功後,就能夠建立redis鏈接了,接下來學習怎樣建立redis鏈接:socket
redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令(好比,SET命令對應與StrictRedis.set方法)。Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。 簡單說,官方推薦使用StrictRedis方法。ide
這裏不推薦使用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()