Flask 鏈接 Redis 數(shù)據(jù)庫
本節(jié)使用 Flask 完成一個訪問 Redis 數(shù)據(jù)庫的例子,通過瀏覽器向用戶提供界面,在服務(wù)端使用 Flask 完成增、刪、改、查 Redis 數(shù)據(jù)庫的操作。
傳統(tǒng)的關(guān)系數(shù)據(jù)庫在超大規(guī)模和高并發(fā)類型的 web2.0 純動態(tài)網(wǎng)站已經(jīng)顯得力不從心,暴露了很多難以克服的問題,而非關(guān)系型的數(shù)據(jù)庫則由于其本身的特點得到了非常迅速的發(fā)展。Redis 是是一個高性能的 key-value 數(shù)據(jù)庫,可以有效應(yīng)對高并發(fā)、大數(shù)據(jù)量訪問的難題。
1. 程序功能介紹
程序提供了如下功能:
- 向 Redis 數(shù)據(jù)庫中插入一條數(shù)據(jù);
- 向 Redis 數(shù)據(jù)庫中批量插入多條數(shù)據(jù);
- 從 Redis 數(shù)據(jù)庫中刪除指定數(shù)據(jù);
- 修改 Redis 數(shù)據(jù)庫中的現(xiàn)有數(shù)據(jù);
- 從 Redis 數(shù)據(jù)庫中查詢所有的數(shù)據(jù)。
用戶通過瀏覽器對 Redis 數(shù)據(jù)庫進行操作,界面如下所示:
2. 源程序下載
例子包括 3 個源文件,如下表所示:
源文件 | 說明 |
---|---|
app.py |
Flask 后端程序,對 Redis 數(shù)據(jù)庫進行操作 |
templates/index.html | 首頁模板,提供增、刪、改、查的操作界面 |
templates/query.html | 查詢結(jié)果模板,返回當(dāng)前數(shù)據(jù)庫中的內(nèi)容 |
3. 首頁模板
首頁模板 templates/index.html 展示了對 Redis 數(shù)據(jù)庫增、刪、改、查的操作界面,templates/index.html 分為 5 個部分:
3.1 查詢數(shù)據(jù)
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h2>查詢數(shù)據(jù)</h2>
<form action="/query", method="post">
<input type="submit" value="查詢">
</form>
在第 2 行,定義表單 form 描述了查詢數(shù)據(jù)的界面,使用 POST 方法提交給服務(wù)端的 /query 頁面進行處理。
3.2 插入數(shù)據(jù)
<h2>插入數(shù)據(jù)</h2>
<form action="/insert", method="post">
<input type="text" name="key" placeholder="鍵名">
<input type="text" name="value" placeholder="鍵值">
<input type="submit" value="插入">
</form>
在第 2 行,定義表單 form 描述了插入數(shù)據(jù)的界面,使用 POST 方法提交給服務(wù)端的 /insert 頁面進行處理;在第 3 行和第 4 行,表單中包含有兩個字段 key 和 value,作為插入 Redis 數(shù)據(jù)庫的鍵和值。
3.3 批量插入數(shù)據(jù)
<h2>批量插入數(shù)據(jù)</h2>
<form action="/insertMulti", method="post">
<input type="text" name="keyA" placeholder="鍵名">
<input type="text" name="valueA" placeholder="鍵值">
<br>
<input type="text" name="keyB" placeholder="鍵名">
<input type="text" name="valueB" placeholder="鍵值">
<input type="submit" value="插入">
</form>
在第 2 行,定義表單 form 描述了插入數(shù)據(jù)的界面,使用 POST 方法提交給服務(wù)端的 /insertMulti 頁面進行處理;在第 3 行和第 4 行,表單中包含有兩個字段 keyA 和 valueA;在第 6 行和第 7 行,表單中包含有兩個字段 keyB 和 valueB;這兩組鍵值對:keyA 和 valueA、keyB 和 valueB 會被批量插入到 Redis 數(shù)據(jù)庫。
3.4 刪除數(shù)據(jù)
<h2>刪除數(shù)據(jù)</h2>
<form action="/delete", method="post">
<input type="text" name="key" placeholder="鍵名">
<input type="submit" value="刪除">
</form>
<h2>刪除所有數(shù)據(jù)</h2>
<form action="/deleteAll", method="post">
<input type="submit" value="刪除">
</form>
在第 2 行,定義表單 form 描述了刪除數(shù)據(jù)的界面,使用 POST 方法提交給服務(wù)端的 /delete 頁面進行處理;在第 3 行,表單中包含字段 key,指定被刪除的鍵。
在第 8 行,定義表單 form 描述了刪除所有數(shù)據(jù)的界面,使用 POST 方法提交給服務(wù)端的 /deleteAll 頁面進行處理。
3.5 修改數(shù)據(jù)
<h2>修改數(shù)據(jù)</h2>
<form action="/update", method="post">
<input type="text" name="key" placeholder="鍵名">
<input type="text" name="value" placeholder="鍵值">
<input type="submit" value="修改">
</form>
</body>
</html>
在第 2 行,定義表單 form 描述了修改數(shù)據(jù)的界面,使用 POST 方法提交給服務(wù)端的 /update 頁面進行處理;在第 3 行和第 4 行,表單中包含有兩個字段 key 和 value,作為修改 Redis 數(shù)據(jù)庫的鍵和值。
4. 查詢結(jié)果模板
查詢結(jié)果頁面返回 Redis 數(shù)據(jù)庫中全部的鍵值對,頁面模板文件 templates/query.html 的內(nèi)容如下:
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>全部的鍵值對</h1>
<table border=1 cellpadding=0>
<tr>
<td>鍵</td>
<td>值</td>
</tr>
{% for key in dict %}
<tr>
<td>{{ key }}</td>
<td>{{ dict[key] }}</td>
</tr>
{% endfor %}
</table>
<br>
<a href="/">返回主頁</a>
</body>
</html>
在第 8 行,定義了一個 table,使用 table 顯示全部的鍵值對,table 包含 2 列,第 1 列顯示鍵,第 2 列顯示值;在第 13 行,F(xiàn)lask 程序傳遞給頁面模板一個參數(shù) dict,參數(shù) dict 包含有 Redis 數(shù)據(jù)庫的鍵值對,使用 for 循環(huán)顯示 dict 中的鍵值對。
假設(shè) Redis 數(shù)據(jù)庫中包括 3 個鍵值對:
- ‘www’:‘WWW’;
- ‘imooc’:‘IMOOC’;
- ‘com’:‘COM’。
則 /query 界面如下圖所示:
5. 后端 Flask 程序
服務(wù)端的 Flask 程序 app.py 提供了對 Redis 數(shù)據(jù)庫增、刪、改、查的操作。
5.1 安裝相關(guān)模塊
flask 操作 Redis 數(shù)據(jù)庫需要使用 redis 第三方模塊,redis 需要單獨安裝,如果你的環(huán)境中沒有 redis,可以使用下面這條命令安裝:
$ pip3 install redis
5.2 引入相關(guān)模塊
#!/usr/bin/python3
from flask import Flask, render_template, request
import redis
app = Flask(__name__)
db = redis.Redis(host='localhost', decode_responses=True)
首先引入模塊 flask 和 redis,其中 flask.request 對象用于獲取表單參數(shù)。
在第 6 行,創(chuàng)建 Redis 數(shù)據(jù)庫連接對象,在默認情況下,Redis 數(shù)據(jù)庫返回的結(jié)果是字節(jié),通過設(shè)定參數(shù) decode_responses=True 使 Redis 返回字符串。
5.2 展示首頁面
@app.route('/')
def index():
return render_template('index.html')
訪問首頁面時,使用函數(shù) index () 進行處理,函數(shù) index () 渲染模板文件 index.html。
5.3 查詢數(shù)據(jù)
@app.route('/query', methods = ['post'])
def query():
keys = db.keys()
dict = {}
for key in keys:
value = db.get(key)
dict[key] = value
return render_template('query.html', dict = dict)
用戶查詢數(shù)據(jù)時,通過 POST 方法將表單提交給 /query 頁面,F(xiàn)lask 應(yīng)用將請求轉(zhuǎn)發(fā)給函數(shù) query () 處理。
函數(shù) query () 通過調(diào)用 db.keys () 獲取 Redis 數(shù)據(jù)庫中所有的鍵,調(diào)用 db.get (key) 獲取鍵對應(yīng)的值,創(chuàng)建一個字典 dict 存儲查詢結(jié)果,最后將 dict 作為參數(shù)傳遞給模板 query.html,模板 query.html 以 table 的形式展現(xiàn)鍵值對,如下圖所示:
5.4 插入數(shù)據(jù)和修改數(shù)據(jù)
@app.route('/insert', methods = ['post'])
@app.route('/update', methods = ['post'])
def insert():
key = request.form['key']
value = request.form['value']
db.set(key, value)
return query()
在 Redis 數(shù)據(jù)庫中,插入數(shù)據(jù)和修改數(shù)據(jù)使用相同的操作,因此可以使用相同的函數(shù)處理插入數(shù)據(jù)和修改數(shù)據(jù)。在第 3 行,定義了函數(shù) insert,它是兩個頁面的處理函數(shù):
- 用戶插入單條數(shù)據(jù)時,通過 POST 方法將表單提交給 /insert 頁面,F(xiàn)lask 應(yīng)用將請求轉(zhuǎn)發(fā)給函數(shù) insert () 處理;
- 用戶修改數(shù)據(jù)時,通過 POST 方法將表單提交給 /update 頁面,F(xiàn)lask 應(yīng)用將請求轉(zhuǎn)發(fā)給函數(shù) insert () 處理。
通過 request.form [‘key’] 獲取表單中的 key 字段,通過 request.form [‘key’] 獲取表單中的 value 字段,使用 db.set (key, value) 將鍵值對插入到 Redis 數(shù)據(jù)庫中。
最后,調(diào)用函數(shù) query () 返回數(shù)據(jù)庫查詢的結(jié)果,結(jié)果會顯示出新插入的鍵值對。
@app.route('/insertMulti', methods = ['post'])
def insertMulti():
keyA = request.form['keyA']
valueA = request.form['valueA']
keyB = request.form['keyB']
valueB = request.form['valueB']
db.mset({keyA:valueA, keyB:valueB})
return query()
用戶插入多條數(shù)據(jù)時,通過 POST 方法將表單提交給 /insertMulit 頁面,F(xiàn)lask 應(yīng)用將請轉(zhuǎn)發(fā)給函數(shù) insertMulti () 處理。表單中包含有 2 組鍵值對:keyA 與 valueA、keyB 與 valueB,使用 db.mset ({keyA:valueA, keyB:valueB}) 將這 2 組鍵值對批量插入到 Redis 數(shù)據(jù)庫中。
最后,調(diào)用函數(shù) query () 返回數(shù)據(jù)庫查詢的結(jié)果,即數(shù)據(jù)庫當(dāng)前包含有哪些鍵值對。
5.5 刪除數(shù)據(jù)
@app.route('/delete', methods = ['post'])
def delete():
key = request.form['key']
db.delete(key)
return query()
用戶刪除單條數(shù)據(jù)時,通過 POST 方法將表單提交給 /delete 頁面,F(xiàn)lask 應(yīng)用將請轉(zhuǎn)發(fā)給函數(shù) delete () 處理。函數(shù) delete () 調(diào)用 db.delete (key) 刪除數(shù)據(jù)庫中指定的鍵。
最后,調(diào)用函數(shù) query () 返回數(shù)據(jù)庫查詢的結(jié)果,即數(shù)據(jù)庫當(dāng)前包含有哪些鍵值對。
@app.route('/deleteAll', methods = ['post'])
def deleteAll():
db.flushall()
return query()
用戶刪除全部數(shù)據(jù)時,通過 POST 方法將表單提交給 /deleteAll 頁面,F(xiàn)lask 應(yīng)用將請轉(zhuǎn)發(fā)給函數(shù) deleteAll () 處理。函數(shù) deleteAll () 調(diào)用 db.flushall () 刪除數(shù)據(jù)庫中全部的鍵值對。
最后,調(diào)用函數(shù) query () 返回數(shù)據(jù)庫查詢的結(jié)果,即數(shù)據(jù)庫當(dāng)前包含有哪些鍵值對。
5.6 啟動 Flask 程序
最后調(diào)用 app.run () 啟動 Flask 程序:
app.run()
6. 小結(jié)
本節(jié)講解了訪問 redis 數(shù)據(jù)庫的相關(guān) API,使用思維導(dǎo)圖概括如下: