1. 程式人生 > Python進階應用教學 >29 使用 Python 操作 Redis 資料庫

29 使用 Python 操作 Redis 資料庫

1. 簡介

Redis 是是一個高效能的 key-value 資料庫。Redis 支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。 Redis不僅僅支援簡單的 key-value 型別的資料,同時還提供 list、set、zset、hash 等資料結構的儲存。

Python 程式要訪問 Redis,需要使用第三方模組 redis。

2. 安裝模組 redis

redis 是 python 訪問 Redis 資料庫的模組。首先檢查是否已經安裝了 redis 模組,在 python 互動模式下 import redis,如下所示:

>>> import
redis Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'redis'

如果出現錯誤:ModuleNotFoundError,則表示還沒有安裝 redis,使用 pip3 install mysql 安裝 redis,如下所示:

$ pip3 install redis
Collecting redis
...
Installing collected packages: redis
Successfully installed redis-3.5.3

3. 連線 redis 資料庫

使用 redis.Redis() 方法連線 redis 資料庫,示例如下:

>>> import redis
>>> db = redis.Redis(host='localhost')
>>> db.set('name', 'ZhangSan')
True
>>> db.get('name')
b'ZhangSan'
  • 在第 1 行,引入 redis 模組
  • 在第 2 行,使用 redis.Redis() 方法連線 redis 資料庫,返回一個數據庫連線物件 db
  • 在第 3 行,設定鍵 ‘name’ 的值為 ‘ZhangSan’
  • 在第 5 行,獲取鍵 ‘name’ 的值
  • 在第 6 行,redis 資料庫返回的是位元組物件 b’ZhangSan’,而不是字串 ‘ZhangSan’

在預設情況下,redis 返回的結果是位元組物件,通過設定引數 decode_responses=True 使 redis 返回字串。示例如下:

>>> import redis
>>> db = redis.Redis(host='localhost', decode_responses=True)
>>> db.set('name', 'ZhangSan')
True
>>> db.get('name')
'ZhangSan'
  • 在第 2 行,使用 decode_responses=True 的方式連線 redis 資料庫
  • 在第 6 行,redis 資料庫返回的是字串 ‘ZhangSan’,而不是位元組物件 b’ZhangSan’

在接下來的小節中,我們使用 decode_responses=True 的方式連線 redis 資料庫,通過資料庫連線物件 db 向 redis 資料庫傳送命令。以上連線 redis 資料庫的程式碼將不再重複。

4. 根據鍵訪問

4.1 設定和獲取一個鍵

>>> db.set('name', 'imooc')
True
>>> db.get('name')
'imooc'
  • 在第 1 行,設定鍵 ‘name’ 的值為 ‘imooc’
  • 在第 3 行,獲取鍵 ‘name’ 的值

4.2 設定和獲取多個鍵

>>> db.mset({'name': 'ZhangSan', 'age': 30})
True
>>> db.mget('name', 'age')
['ZhangSan', '30']
>>> db.mget(['name', 'age'])
['ZhangSan', '30']
  • 在第 1 行,設定兩個鍵
    • 設定鍵 ‘name’ 的值為 ‘ZhangSan’
    • 設定鍵 ‘age’ 的值為 30
  • 在第 3 行,獲取兩個鍵的值
    • mget 返回一個記錄了兩個鍵值的陣列
  • 在第 5 行,獲取兩個鍵的值的另一種呼叫方式

4.2 刪除鍵

>>> db.set('name', 'ZhangSan')
>>> db.get('name')
'ZhangSan'
>>> db.delete('name')
1
>>> db.get('name')
>>> db.get('name') == None
True
  • 在第 1 行,設定鍵 ‘name’ 的值為 ‘ZhangSan’
  • 在第 4 行,使用 delete() 方法刪除鍵 ‘name’
  • 刪除鍵 ‘name’ 後,db.get(‘name’) 返回 None

5. 訪問字串

5.1 獲取字串的長度

>>> db.set('name', 'www.imooc.com')
True
>>> db.strlen('name')
13
  • 在第 1 行,設定鍵 ‘name’ 的值為字串 ‘www.imooc.com
  • 在第 3 行,通過 strlen() 方法獲取鍵 ‘name’ 的值的長度

5.2 獲取字串的子串

>>> db.getrange('name', 0, 2)
'www'
>>> db.getrange('name', 4, 8)
'imooc'
>>> db.getrange('name', 10, 12)
'com'
>>>
  • 在第 1 行,獲取字串中範圍為 [0, 2] 的子串,即 ‘www’
  • 在第 3 行,獲取字串中範圍為 [4, 8] 的子串,即 ‘imooc’
  • 在第 5 行,獲取字串中範圍為 [10, 12] 的子串,即 ‘com’

5.3 設定字串的子串

>>> db.setrange('name', 4, 'IMOOC')
13
>>> db.get('name')
'www.IMOOC.com'
  • 在第 1 行,將字串中從 4 開始的子串 ‘imooc’,替換為 ‘IMOOC’

6. 訪問列表

6.1 建立列表

>>> db.rpush('url', 'www')
1
>>> db.rpush('url', 'imooc')
2
>>> db.rpush('url', 'com')
3
  • 方法 rpush(list, value) 將值 value 新增到列表 list 的尾部
    • 如果列表 list 不存在,會建立一個空列表
  • 在第 1 行,建立一個列表 url,將字串 ‘www’ 新增到列表的尾部
  • 在第 2 行,將字串 ‘imooc’ 新增到列表的尾部
  • 在第 3 行,將字串 ‘com’ 新增到列表的尾部

6.2 訪問列表

>>> db.llen('url')
3
>>> db.lindex('url', 0)
'www'
>>> db.lindex('url', 1)
'imooc'
>>> db.lindex('url', 2)
'com'
  • 在第 1 行,方法 llen(‘url’) 返回列表 url 的長度
  • 在第 3 行,llindex(‘url’, 0) 返回列表 url 中第 0 項的資料
  • 在第 5 行,llindex(‘url’, 1) 返回列表 url 中第 1 項的資料
  • 在第 7 行,llindex(‘url’, 2) 返回列表 url 中第 2 項的資料

6.3 獲取指定範圍的元素

>>> db.lrange('url', 0, 1)
['www', 'imooc']
>>> db.lrange('url', 0, 2)
['www', 'imooc', 'com']
  • lrange(start, stop) 返回列表中指定區間 [start, stop] 內的元素
  • 在第 1 行,獲取列表 url 中範圍 [0, 1] 內的 2 項元素
  • 在第 3 行,獲取列表 url 中範圍 [0, 2] 內的 3 項元素

6.4 在列表中插入資料

>>> db.lrange('url', 0, 2)
['www', 'imooc', 'com']
>>> db.linsert('url', 'after', 'www', '.')
4
>>> db.linsert('url', 'before', 'com', '.')
5
>>> db.lrange('url', 0, 4)
['www', '.', 'imooc', '.', 'com']
  • 在第 3 行,在資料項 ‘www’ 的後面,插入資料項 ‘.’
  • 在第 5 行,在資料項 ‘com’ 的前面,插入資料項 ‘.’
  • 在第 8 行,結果顯示
    • 在 ‘www’ 和 ‘imooc’ 之間增加了一項 ‘.’
    • 在 ‘imooc’ 和 ‘com’ 之間增加了一項 ‘.’

6.5 修改列表

>>> db.lindex('url', 1)
'imooc'
>>> db.lset('url', 1, 'IMOOC')
True
>>> db.lindex('url', 1)
'IMOOC'
  • 在第 1 行,顯示列表 ‘url’ 的第 1 項內容為 ‘imooc’
  • 在第 3 行,將列表 ‘url’ 的第 1 項內容修改為 ‘IMOOC’
  • 在第 5 行,顯示列表 ‘url’ 的第 1 項內容為 ‘IMOOC’

6.6 將列表作為堆疊

>>> db.rpush('stack', 'www')
1
>>> db.rpush('stack', 'imooc')
2
>>> db.rpush('stack', 'com')
3
>>> db.llen('stack')
3
  • 方法 rpush(list, value) 將資料增加到列表 list 尾部,相當於堆疊的 push 操作
  • 將 3 個字串 ‘www’、‘imooc’、‘com’ 依次壓入到堆疊 stack 中
  • 此時堆疊 stack 的長度為 3
>>> db.rpop('stack')
'com'
>>> db.rpop('stack')
'imooc'
>>> db.rpop('stack')
'www'
>>> db.llen('stack')
0
  • 方法 rpop(list) 將資料從列表 list 尾部刪除,相當於堆疊的 pop 操作
  • 從堆疊 stack 中依次彈出 ‘com’、‘imooc’、‘www’
  • 此時堆疊 stack 的長度為 0

7. 訪問集合

7.1 建立集合

>>> db.sadd('set', 'a')
1
>>> db.sadd('set', 'b')
1
>>> db.sadd('set', 'c')
1
  • 方法 sadd(set, value) 向集合 set 中新增元素 value
    • 如果集合 set 不存在,則建立一個集合
  • 在第 1 行,向集合 ‘set’ 新增元素 ‘a’
  • 在第 3 行,向集合 ‘set’ 新增元素 ‘b’
  • 在第 5 行,向集合 ‘set’ 新增元素 ‘c’

7.2 獲取集合的成員

>>> db.scard('set')
3
>>> db.smembers('set')
{'b', 'c', 'a'}
  • 在第 1 行,使用方法 scard(‘set’) 獲取集合的元素的數量
  • 在第 3 行,使用方法 smembers(‘set’) 獲取集合的所有元素
>>> db.sismember('set', 'b')
True
>>> db.sismember('set', 'd')
False
  • 在第 1 行,使用方法 sismember(‘set’, ‘b’) 檢查集合 ‘set’ 是否包含 ‘b’
  • 在第 3 行,使用方法 sismember(‘set’, ‘d’) 檢查集合 ‘set’ 是否包含 ‘d’

7.3 求集合的交、並、差

>>> db.sadd('set2', 'b')
1
>>> db.sadd('set2', 'c')
1
>>> db.sadd('set2', 'd')
1
  • 建立集合 ‘set2’,向集合 ‘set2’ 中新增元素 ‘b’、‘c’、‘d’
>>> db.smembers('set')
{'a', 'b', 'c'}
>>> db.smembers('set2')
{'b', 'd', 'c'}
  • 顯示集合 ‘set’ 與 集合 ‘set2’ 包含的成員
>>> db.sinter('set', 'set2')
{'b', 'c'}
>>> db.sunion('set', 'set2')
{'a', 'b', 'd', 'c'}
  • db.sinter(‘set’, ‘set2’) 求取集合的交集
  • db.sunion(‘set’, ‘set2’) 求取集合的並集
>>> db.sdiff('set', 'set2')
{'a'}
>>> db.sdiff('set2', 'set')
{'d'}
  • db.sdiff(‘set’, ‘set2’) 求取集合的差集
    • 在 ‘set’ 中出現,在 ‘set2’ 中沒有出現的元素構成的集合
  • db.sdiff(‘set2’, ‘set’) 求取集合的差集
    • 在 ‘set2’ 中出現,在 ‘set’ 中沒有出現的元素構成的集合

8. 訪問雜湊

8.1 建立雜湊表

>>> db.hset('person', 'name', 'ZhangSan')
1
>>> db.hset('person', 'age', 20)
1
  • 方法 hset(hash_table, key, value),向雜湊表 hash_table 增加一組鍵值對,鍵為 key、值為 value
    • 如果雜湊表 hash_table 不存在,則建立一個新的雜湊表
  • 建立一個雜湊表 person,描述一個人,包括兩項屬性:name 和 age
  • 在第 1 行,為雜湊表 person 增加一組鍵值對:鍵為 ‘name’、值為 ‘ZhangSan’
  • 在第 3 行,為雜湊表 person 增加一組鍵值對:鍵為 ‘age’、值為 20
>>> db.hlen('person')
2
  • 方法 hlen(hash_table) 獲取 hash_table 中鍵值對的數目

8.2 訪問雜湊表

>>> db.hget('person', 'name')
'ZhangSan'
>>> db.hget('person', 'age')
'20'
  • 方法 hget(hash_table, key) 獲取雜湊表 hash_table 中鍵為 key 對應的值
  • 在第 1 行,獲取雜湊表 ‘person’ 中鍵為 ‘name’ 的值
  • 在第 3 行,獲取雜湊表 ‘person’ 中鍵為 ‘age’ 的值
>>> db.hexists('person', 'name')
True
>>> db.hexists('person', 'gender')
False
  • 方法 hexists(hash_table, key) 返回雜湊表 hash_table 是否包含鍵 key
  • 在第 1 行,獲取雜湊表 ‘person’ 是否包含 ‘name’
  • 在第 3 行,獲取雜湊表 ‘person’ 是否包含 ‘gender’

8.3 獲取所有的鍵和值

>>> db.hkeys('person')
['name', 'age']
>>> db.hvals('person')
['ZhangSan', '20']
>>> db.hgetall('person')
{'name': 'ZhangSan', 'age': '20'}
  • 方法 hkeys(hash_table) 返回 hash_table 中所有的鍵
  • 方法 hvals(hash_table) 返回 hash_table 中所有的值
  • 方法 hgetall(hash_table) 返回一個字典,描述 hash_table 中所有的鍵和值

8.4 遍歷雜湊表

>>> keys = db.hkeys('person')
>>> for key in keys:
...     val = db.hget('person', key)
...     print('%s:%s' % (key, val))
...
name:ZhangSan
age:20
  • 在第 1 行,通過 hkeys() 方法獲取所有的鍵
  • 在第 2 行,使用 for 迴圈遍歷所有的鍵
  • 在第 3 行,使用 hget() 方法獲取指定鍵對應的值
>>> dict = db.hgetall('person')
>>> for key,val in dict.items():
...     print('%s:%s' % (key, val))
...
name:ZhangSan
age:20
  • 在第 1 行,通過 hgetall() 方法獲取所有的鍵值對,該方法返回一個字典
  • 遍歷 hgetall() 返回的字典

8.5 增加鍵和刪除鍵

>>> db.hset('person', 'gender', 'female')
1
>>> db.hgetall('person')
{'name': 'ZhangSan', 'age': '20', 'gender': 'female'}
>>> db.hdel('person', 'gender')
1
>>> db.hgetall('person')
{'name': 'ZhangSan', 'age': '20'}
  • 在第 1 行,為雜湊表 ‘person’ 增加一個鍵 ‘gender’,值為 ‘female’
  • 在第 3 行,使用方法 hgetall(‘person’) 顯示雜湊表 ‘person’ 的鍵值對
    • 已經增加了一個鍵 ‘gender’
  • 在第 5 行,使用方法 hdel(‘person’, ‘gender’) 刪除雜湊表 ‘person’ 中的鍵 ‘gender’
  • 在第 7 行,使用方法 hgetall(‘person’) 顯示雜湊表 ‘person’ 的鍵值對
    • 已經刪除了鍵 ‘gender’