Flask:操做SQLite3(0.1)

Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2html

 

本文介紹了第一次在Flask框架中操做SQLite3數據庫的測試,參考了官網的文檔Using SQLite 3 with Flask,直接使用了裏面定義前端

的幾個函數:init_db、get_db、close_connection、make_dicts,另外,本身編寫了視圖(View)函數實現添加、讀取操做。sql

 

本測試項目的目標數據庫

-使用建模文件初始化數據庫成功flask

-鏈接數據庫成功api

-關閉數據庫成功瀏覽器

-添加數據成功session

-讀取數據成功,併成功返回到頁面app

 

測試步驟框架

1.創建空的SQLite3數據庫文件 和 數據庫建模文件

前面一篇關於SQLite3的文章有介紹,使用sqlite3.exe便可;

數據庫建模文件,參考SQLite官方文檔SQL As Understood By SQLite創建;

下面是個人建模文件內容:

1 DROP TABLE IF EXISTS post;
2 CREATE TABLE post (
3     id INTEGER PRIMARY KEY AUTOINCREMENT,
4     body VARCHAR(500) NOT NULL,
5     created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
6 );

若是原數據庫存在,就刪除,而後創建新的。

數據表post,包括id、body、created三個字段,其中,body字段爲提交的消息,created爲消息存放到數據庫的時間。

 

創建好的數據庫文件和建模文件放到項目的db文件夾下:

 

說明,數據庫文件和建模文件不必定要放到db文件夾下,也能夠放到Flask項目的根目錄下(Q:是否能夠放到項目以外呢?不建議。),只要程序中把相關路徑輸入正確便可。

 

2.編寫Flask項目文件main.py(單模塊項目)

將文檔Using SQLite 3 with Flask中的一些代碼拷貝到many.py中。

 1 from flask import * # 導入flask模塊下的全部元素
 2 import sqlite3 # 導入sqlite3模塊
 3 
 4 app = Flask('Posts') # 創建Flask應用
 5 
 6 DATABASE = 'db/posts.db' # 數據庫文件地址
 7 DATABASE_INIT_FILE = 'db/init.sql' # 數據庫建模文件地址
 8 
 9 # init_db()
10 def init_db(): # 此函數要使用 數據庫建模文件 初始化數據庫:創建post表(Initial Schemas)。此函數在命令行中使用,僅一次,再次使用會刪除數據庫中已有數據11     with app.app_context(): # 官網文檔說了緣由:不是在Web應用中使用,而是在Python Shell中使用時須要此語句Connect on Demand)。
12         db = get_db()
13         with app.open_resource(DATABASE_INIT_FILE, mode='r') as f: # with語句用法!
14             db.cursor().executescript(f.read()) # 執行建模文件中的腳本
15         db.commit() # 提交事務
16 
17 # make_dicts()
18 def make_dicts(cursor, row): # 將查詢返回的數據的轉換爲字典類型,這樣會跟方便使用。此函數會在get_db()函數中用到,賦值給db.row_factory。
19     return dict((cursor.description[idx][0], value)
20                 for idx,value in enumerate(row))
21 
22 # get_db()
23 def get_db(): # 獲取數據庫鏈接
24     db = getattr(g, '_database', None) # g對象時一個Flask應用的公共對象(和request、session同樣),用於存儲用戶的數據——整個應用共享!
25     if db is None:
26         db = g._database = sqlite3.connect(DATABASE) # 創建數據庫鏈接
27         db.row_factory = make_dicts # 轉換默認的查詢數據類型爲字典類型,也可使用sqlite3.Row
28     return db # 返回數據庫鏈接,可能返回爲None
29 
30 # close_connection()
31 @app.teardown_appcontext # 這個裝飾器用於實如今請求的最後自動關閉數據庫鏈接的功能
32 def close_connection(exception): # 關閉數據庫鏈接
33     db = getattr(g, '_database', None)
34     if db is not None:
35         db.close()

 

說明,在謄寫代碼過程當中,把cursor.description寫錯了,直到最後運行程序才發現了錯誤。

 

以上,初始化數據庫——只執行一次、獲取數據庫鏈接、關閉數據庫鏈接的程序都有了。接下來,創建一個視圖函數測試數據庫鏈接、關閉數據庫鏈接是否正常執行。

注意,在此時以前須要再get_db、close_connection函數中添加調試語句,print或者app.logger均可以。

1 @app.route('/testdb')
2 def testdb():
3     get_db()
4     return "After test"

而後,啓動Flask項目,使用瀏覽器訪問/testdb,檢查項目命令行便可看到添加的調試語句——提示錯誤就繼續修改。

 

3.使用 建模文件 初始化 數據庫文件

這個時候須要用到上面的init_db()函數了。

在文檔Using SQLite 3 with Flask的Initial Schemas中有介紹,將Flask項目模塊的init_db()函數導入,再執行便可。

下面是個人測試狀況:成功 按照建模文件 創建 數據表post

注意,在Python Shell執行上面的命令時,須要保證當前目錄爲Flask項目所在目錄。

 

4.創建測試項目須要視圖函數(View functions)

本測試項目須要實現發佈消息、展現消息的功能(但並無作到同一個頁面上),所以,創建了三個視圖函數來實現目標:

4.1 home()

首頁,返回一個模板用於添加post。

此模板文件僅包含靜態內容,所以,render_template只有一個參數。

1 # path: /
2 # show posts
3 @app.route('/')
4 def home():
5     return render_template('temp.html')

模板文件主要內容:定義表單,action爲「pureadd」

1 <form action="pureadd" method="post">
2     <textarea name="newpost" style="width:200px;height:100px;" maxlength="500"></textarea><br />
3     <input type="submit" value="添加" /> 
4 </form>
5 <a href="/pureshow">展現帖子</a><br />

頁面以下:

 

4.2 pureadd()

一個單純地(pure)用於添加一條post到數據庫的視圖函數,會對參數進行校驗、發生錯誤時會返回錯誤的信息等。

僅支持POST方法的請求。

此視圖的返回信息中還包括跳轉到添加頁面、展現頁面的連接。

 1 # pure add page for test
 2 @app.route('/pureadd', methods=['POST'])
 3 def pureadd():
 4     # step 1. get the new post and check the data
 5     newp = ''
 6     try:
 7         newp = request.form['newpost']
 8     except:
 9         return 'ERROR: Invalid form parameters!'
10     
11     print('newp = "', newp, '"')
12     
13     newp2 = newp.strip() # 清理post兩遍的空格,而後賦值給新變量——此時舊變量沒有改變
14     
15     if newp2 == '':
16         return 'Warning: New post is empty!<br/>' \
17             '<a href="/">繼續添加</a><br/>' \
18             '<a href="/pureshow">展現帖子</a><br />'
19     
20     # step 2.write the new post into database
21     sqlmode = 'INSERT INTO post(body) VALUES(?)' # 添加數據的SQL語句,佔位符使用問號(?)。須要注意的是,若是是MySQL,佔位符是百分號(%)。
22     try:
23         db = get_db()
24         cursor = db.cursor()
25         cursor.execute(sqlmode, (newp2,))
26         cursor.close() # 關閉cursor。Q:是否必定要關閉呢?不關閉有什麼影響?
27         db.commit() # 須要commit,不然,數據不會更新到數據庫 28     except Exception as e:
29         return '<span style="color:red;">INFO: New post added failed <br/> %s</span><br/>' \
30             '<a href="/">繼續添加</a><br/>' \
31             '<a href="/pureshow">展現帖子</a><br />' % str(e)
32     else:
33         return 'INFO: New post added <br/><pre>[%s]</pre><br/>' \
34             '<a href="/">繼續添加</a><br/>' \
35             '<a href="/pureshow">展現帖子</a><br />' % newp

 

成功添加一條數據:

 

數據庫中顯示添加的數據:

 

4.3 pureshow()

此視圖函數用於 展現數據庫中的數據。

將查詢到的數據直接返回到 模板文件showall.html 中。

注意,須要提一下前面get_db()函數中的設置db.row_factory爲make_dicts。若是沒有這個賦值的話,模板文件的解析數據方式將會改變。

 1 # pure show page for test
 2 @app.route('/pureshow')
 3 def pureshow():
 4     sqlmode = "SELECT * FROM post ORDER BY created DESC"
 5     rv = []
 6     try:
 7         db = get_db()
 8         cursor = db.execute(sqlmode)
 9         rv = cursor.fetchall()
10         cursor.close()
11     except Exception as e:
12         print(e)
13         abort(500)
14     else:
15         return render_template('showall.html', posts=rv)

模板文件showall.html的主要內容:使用for循環將pureshow()函數返回的內容展現出來

1 <div id="postslist">
2     {% for post in posts %}
3         <div class="post_item" id="post{{ post.id }}">
4             {{ post.body }}<br/>
5             {{ post.created }}
6         </div>
7     {% endfor %}
8 </div>
9 <a href="/">繼續添加</a>

/pureshow頁面展現內容以下:

 

注意,數據庫中保存的時間爲UTC時間,在實際應用中,展現出來時還須要添加對應的時差。

 

參考連接

Using SQLite 3 with Flask

廖雪峯官網 之 使用SQLite(關於佔位符)

 

後續

上面的方法很簡單,在Flask提供的擴展中,有一個叫作SQLAlchemy的,使用它能夠更高效地操做各類數據庫,因此,下一步就是學習並使用它了。

官方文檔SQLAlchemy in Flask中有介紹,看過一遍了,如今,該實踐了。

 

前面作的項目都是基於單個的模型文件的,後面須要升級:基於package的方式使用Blueprint,這兩個是重點啊!

 

在官網的Tutorial會有關於SQLAlchemy、Blueprint的介紹,也是須要參考的。

 

Flask,還須要以周計的時間才能熟練使用啊。

 

本身沒有作過完整的Web應用,在URL設計等方面存在一些挑戰,所以,這個測試項目纔會如此simple。

原本還想實現用戶登陸、退出等「稍微複雜」的功能的——最初的想法,最後都只能放棄了。

我想,在熟悉了SQLAlchemy、Blueprint後,Web開發的功力會有很大提升的。

 

對了,還有就是 怎麼提供數據接口給前端,好比RESTful API等,都是須要熟練的。

相關文章
相關標籤/搜索