Web 應用離不開數據存儲,今天就來學習下 Flask 中如何與數據庫交互,最後咱們將作一個提交的實例html
Flask 中最方便用的數據庫框架是 flask_sqlalchamy,是對 SQLAlchamy 在 Flask 中的擴展, SQLAlchemy 是一個 Python 數據庫工具(ORM,即對象關係映射)。python
藉助 SQLAlchemy,經過定義 Python 類來表示數據庫裏的一張表(類屬性表示表中的字段 或者 列),經過對這個類進行各類操做來代替寫 SQL 語句。這個類咱們稱之爲模型類,類中的屬性咱們將稱之爲字段。sql
SQLAlchemy 支持多種數據庫,對於不一樣的數據庫只須要修改下配置連接就能夠,在這裏咱們使用關係型數據庫 SQLite 做爲演示。shell
SQLite 是基於文件的關係型數據庫,不須要單獨啓動數據庫服務器,適合在開發時使用,或是在數據庫操做簡單、訪問量低的程序中使用。數據庫
pip install flask_sqlalchamy
安裝以後,導入到項目中,對應用進行初始化:flask
from flask import Flaskfrom flask_sqlalchamy import SQLAlchamy # 導入 SQLAlachamy
app = Flask(__name__) # 建立 Flask 應用
db = SQLAlchamy(app) # 初始化應用
數據庫通常做爲第三方應用,須要經過創建與數據庫的鏈接,讓應用能夠是使用數據庫。服務器
常見的數據庫有 MySql、SqlServer、Oracle、SQLite、MongoDB 等等,每種數據庫都有本身特定的鏈接格式,咱們使用的是簡單的 SQLite 數據庫,它的鏈接格式是:session
sqlite:////數據庫文件的絕對地址
注意: 若是您使用 Windows 系統,上面的 URI 前綴部分須要寫入三個斜線 (即 sqlite:///)app
在例子中,將數據庫文件路徑設置爲當前應用的根目錄下:框架
import os# ...app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////' + os.path.join(app.root_path, 'data.db')
注意: 爲了設置 Flask、擴展或是咱們程序自己的一些行爲,須要設置和定義一些配置變量。Flask 提供了一個統一的接口來寫入和獲取這些配置變量:Flask.config 字典。配置變量的名稱必須使用大寫,寫入配置的語句通常會放到擴展類實例化語句以前。app.config 是一種簡便的 Flask 應用的配置方式
模型簡單來講就是數據庫中的一張表定義,須要有名稱,字段,在 Python 中用一個類來表示,因爲須要和數據庫的表對應,模型必須繼承自 SQLAlchamy 的 Model 類
在初始化應用中,咱們獲得一個 SQLAlchamy 的實例 db,定義模型都是繼承自實例的 Model 類的
下面定義一個 Profile 模型,用來記錄一個用戶的基本信息:
class Profile(db.Model): id = db.Column(db.Integer, primary_key=True) # 主鍵 name = db.Column(db.String(20)) birthday = db.Column(db.Date()) createtime = db.Column(db.DateTime()) about = db.Column(db.Text())
經常使用的字段類型以下表所示:
字段類型 | 說明 |
---|---|
db.Integer | 整數 |
db.String(size) | 字符串 size 爲字符串長度 |
db.DateTime | 日期時間 |
db.Date | 日期 |
db.Text | 長文本,能夠存放 CLOB (二進制數據) |
db.Float | 浮點數字 |
db.Boolean | 布爾值 |
定義好數據模型以後,能夠用模型來建立數據庫表,即用模型來管理庫表的建立。
若是已經有了數據,能夠經過
sqlacodegen
或者Flask-SQLAcodegen
工具來由數據庫中庫表定義建立 SQLAlchamy 模型
使用 db.create_all()
能夠將應用中的模型,建立成數據庫中的表,庫表名爲模型名稱的小寫形式。能夠經過 __tablename__
模型類屬性類指定庫表名稱
通常庫表是在初始化應用時建立,因此不必將建立語句寫在應用中,能夠在庫表定義發生變化是單獨使用 Flask-Shell
工具與數據庫同步一次模型定義
在命令行下,將目錄切換到當前項目根目錄執行:
$ flask shell>>> from app import db # app 對應的是應用主代碼文件名,如app.py>>> db.create_all()
執行完成,就會在在項目根目錄下建立一個 data.db 文件,這個文件是配置中設置的 SQLite 數據庫文件
若是變動了模型定義,能夠先調用 db.drop_all()
來刪除數據庫中表的定義,注意 db.drop_all()
刪除數據庫中表的同時,也會刪除數據。
若是須要保留數據,可使用使用數據庫遷移工具,好比集成了 Alembic
的 Flask-Migrate
擴展工具
Flask Shell 打開的 Python Shell 環境並不等於 用 python 打開的環境,Flask Shell 會將當前目錄下的應用做爲環境上下文,因此在執行 Flask Shell 時須要將命令行當前目錄切換到項目所在的目錄下。項目目錄下,應用主代碼文件應該命名爲
app.py
或者wsgi.py
爲了方便說明數據庫的使用,咱們還在上面的用 Flask Shell 打開的 Python Shell 環境下執行代碼
向數據庫中新增記錄
from app import Profile # Profile 是在應用中定義的模型from app import dbimport datetime
# 建立一個 Profile 實例profile = Profile()profile.name = "Tiger"# Date 和 DateTime 類型屬性,必須接受 Python datetime 對象profile.birthday = datetime.datetime(2001, 10, 1)profile.createtime = datetime.datetime.now()profile.about = 'My name is Tiger, come from Beijing China.'
db.session.add(profile) # 將變化添加db.session.commit() # 將變化提交
session
是一個與數據庫通訊的會話,是 SQLAlchamy 框架與數據庫交互的代理,若是要放棄某次變化,能夠調用 session.rollback()
回滾掉未提交的變化,這個和數據庫的事務很類似,但和數據庫的事務沒有關係
能夠經過對模型類的 query
屬性調用可選的過濾方法和查詢方法,獲取到對應的單個或多個記錄(記錄以模型類實例的形式表示)。查詢語句的格式以下:
<模型類>.query.<過濾方法(可選)>.<查詢方法>
例如:
# ... 忽略引入相關代碼profile = Profile.query.first() # 查詢出 profile 表中第一條記錄
profile.name # Tigerprofile.birthday # 2001-10-01 00:00:00profile.about # My name is Tiger, come from Beijing China.profiles = Profile.query.all() # 查詢出全部記錄,返回 Profile 實例列表profile_count = Profile.query.count() # 記錄條數profile = Profile.query.get(1) # 獲取主鍵爲 1 的記錄profile = Profile.filter_by(name='Tiger').first() # 查詢 name 等於 Tiger 的記錄集中第一條記錄profiles = Profile.filter(Profile.name != 'Tiger').all() # 查詢 name 不等於 Tiger 的全部記錄
方法名稱 | 說明 |
---|---|
filter() | 使用指定的規則過濾記錄,返回新產生的查詢對象 |
filter_by() | 使用指定規則過濾記錄(以關鍵字表達式的形式),返回新產生的查詢對象 |
order_by() | 根據指定條件對記錄進行排序,返回新產生的查詢對象 |
group_by() | 根據指定條件對記錄進行分組,返回新產生的查詢對象 |
方法名稱 | 說明 |
---|---|
all() | 返回包含全部查詢記錄的列表 |
first() | 返回查詢的第一條記錄,若是未找到,則返回None |
get(id) | 傳入主鍵值做爲參數,返回指定主鍵值的記錄,若是未找到,則返回None |
count() | 返回查詢結果的數量 |
first_or_404() | 返回查詢的第一條記錄,若是未找到,則返回404錯誤響應 |
get_or_404(id) | 傳入主鍵值做爲參數,返回指定主鍵值的記錄,若是未找到,則返回404錯誤響應 |
paginate() | 返回一個Pagination對象,能夠對記錄進行分頁處理 |
首先將記錄查詢出來,而後對其進行修改,以後調用 db.session.commit()
提交變動,注意這裏再也不須要調用 db.session.add()
了:
profile = Profile.query.get(1) # 查詢出ID爲 1 的記錄profile.about = profile.about + ' I like coding~' # 在簡介中添加些內容db.session.commit() # 必須調用提交,不然將不會被更新到數據庫
也須要將記錄查詢出來,調用 db.seeeion.delete()
,最後提交
profile = Profile.query.get(1) # 查詢出ID爲 1 的記錄db.session.delete(profile) # 刪除記錄db.session.commit() # 提交變動
若是要批量刪除,須要遍歷結果集用上面方法逐個刪除,也可使用 query 屬性或者 filter 的結果進行刪除:
Profile.query.filter(Profile.name == 'Tom').delete() # 按照過濾條件來刪除Profile.query.delete() # 刪除全部記錄db.seesion.commit() # 提交變動
瞭解了數據庫的基本操做以後,就能夠在業務邏輯中編寫數據庫處理代碼了
定義一個視圖函數,將根據查詢參數來找到對應的 Profile 記錄,而且將該送給顯示模板
@app.route('/myprofile/<id>/')def myprofile(id): profile = Profile.query.get(id) # 利用參數 id 讀取數據庫記錄 return render_template('profile.html', profile=profile) # 將結果送給模板作展現
模板代碼 profile.html
:
<h1>{{ profile.name }}'s Info </h1><dt>Name:</dt><dd>{{ profile.name }}</dd><dt>Birthday:</dt><dd>{{ profile.birthday }}</dd><dt>About:</dt><dd>{{ profile.about }} </dd>
啓動應用後,訪問 localhost:5000/myprofile/1
就能夠看到 ID 爲 1 的 Profile 信息。
結合前面講述的 Form 知識,在視圖函數中處理表單中提交的內容,並保存的數據庫,下面是視圖函數:
@app.route('/createprofile/', methods=('GET', 'POST'))def createprofile(): form = MyForm() if form.validate_on_submit(): # 若是表單提交了 用表單數據建立 Profile 對象 profile = Profile() profile.name = form.name.data profile.birthday = form.birthday.data profile.about = form.about.data or ""
db.session.add(profile) db.session.commit() return redirect(url_for('myprofile', id=profile.id)) # 跳轉到展現頁面 else: return render_template('createprofile.html', form=form) # 顯示建立頁面
當判斷表單被提交後,用提交數據建立 Profile 對象,存儲到數據庫,而且跳轉到展現頁面。
本節課程簡單介紹了 Flask 中數據庫技術,主要是藉助 Flask-SQLAlchamy 框架來操做數據庫,以 SQLite 關係數據庫爲例講解了數據的增刪改查操做,最後展現瞭如何在視圖函數中操做數據,以便與 Flask 應用相結合。
示例代碼:Python-100-days-day046
參考
系列文章
第0-40天:從0學習Python 0-40合集