鑑於網上關於flask-SQLAlchemy的實例使用教程良莠不齊,於此寫下工做學習過程當中的使用過程,以便分享交流。python
對於python關於flask有必定了解的高端玩家來講,請轉至flask官方開發文檔。mysql
一.安裝(install)sql
須要有安裝python的PC一臺,介於windows系統用戶比較多,本文章使用的是windows下開發。數據庫
1.建立虛擬flask
爲每個工程建立一個獨立的python運行環境是咱們所須要的,python提供了virtualenv,能夠爲咱們提供這個特殊的需求。windows
配置virtualenv環境緩存
windows環境下運行cmd.exe,使用管理員權限運行。服務器
pip install virtualenv
筆者使用的python版本是3.5.2,該版本中自動配置了pip應用,使用pip指令能夠很方便的下載到你所須要的python拓展庫。 網絡
安裝成功後會出現successfully installed virtualenv字樣。session
PS:若是pip指令沒法使用,請確認python環境下scripts是否包含在系統環境變量中的Path中。
使用控制檯進入你須要配置該虛擬環境的目錄,使用mkdir建立工程的文件夾,筆者建立的工程名爲sqlalchemy_demo
mkdir sqlalchemy_demo
建立虛擬Python運行環境
virtualenv flask
出現以下字樣,說明虛擬環境建立成功
進入工程文件夾,激活虛擬python運行環境
flask\scripts\activate
出現以下字樣顯示,說明進入虛擬python運行環境成功
2.安裝所須要的庫文件
咱們須要兩個庫文件,一個是flask,另外一個是flask-SQLAlchemy。使用pip指令安裝
pip install flask
pip install flask-sqlalchemy
看到以下字樣說明兩個庫文件安裝成功
至此,環境配置階段結束。
二.flask-SQLAlchemy簡介
flask-SQLAlchemy 是一個爲您的flask應用增長SQLAlchemy支持的擴展。
在python擴展庫中其實包含了SQLAlchemy。在版本的不斷疊加後,已經被整合到flask架構中,flask-SQLAlchemy簡化在Flask中SQLAlchemy的使用,提供了有用的默認值和額外的助手來更簡單地完成常見任務。
筆者認爲SQLAlchemy比較精髓的是使用ORM(對象關係映射),相對於傳統鏈接數據庫使用select,update,insert,delete操做數據表來講具備如下特色[1]:
簡單——以最基本的形式建模數據
傳達性——數據庫結構被任何人都能理解的語言文檔化
精確性——基於數據模型建立正確標準化的結構
完事無絕對,ORM有明顯的優點,就會想伴隨有缺點。
隱蔽性——相對於傳統使用select,update,insert,delete來講,隱藏了操做數據表的具體操做,不利於SQL的學習
數據表結構修改難——在設計中有時會忽略了一些字段的定義,在ORM模式中只能更新映射表更新字段,並且效果遠不如alter table [表名] add 字段名更新字段來的容易理解,經常會忽略一些細節
但不得不說,ORM模式的確打開了新世界的大門,大大減小了學習及使用數據庫的過程與難度。
三.在實例中應用
1.文件結構
sqlalchemy_demo--->flask
--->database.py
--->model.py
--->test.py
2.建立SQLAlchemy配置文件
database.py代碼以下所示
from flask import Flask from flask_sqlalchemy import SQLAlchemy import os basedir = os.path.abspath(os.path.dirname(__file__)) app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'test.db') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) def db_init(): db.create_all()
一句一句解釋
(1)from flask import Flask
Flask類是flask框架的核心類,它實現了WSGI應用規範。
(2)from flask_sqlalchemy import SQLAlchemy
將flask-sqlchemy中內置的SQLAlchemy引用到該文件下。
(3)import OS
本實例中須要將數據庫建立在工程的更目錄下,使用python內置os庫能夠很方便的定位到工程路徑下。
(4)basedir = os.path.abspath(os.path.dirname(__file__))
將當前文件傳入dirname函數中,獲取當前文件所在路徑,abspath函數獲取該文件所在的絕對路徑,以便在後邊配置建立數據庫的路徑使用。
(5)app = Flask(__name__) [2]
Flask構造函數的第一個參數指定一個引入參數/importname。
Flask框架使用這個名字進行靜態資源、模板、錯誤信息的定位。除非你清楚的理解它的做用,一般狀況下,咱們總應該使用特殊變量__name__。
Flask實例是可調用的(具備call方法),這個實例能夠直接對接 WSGI服務器。
(6)app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'test.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
SQLALCHEMY_DATABASE_URI:用於鏈接數據庫
eg:sqlite:////tmp/test/db
mysql://username:password@server/db
SQLALCHEMY_TRACK_MODIFICATIONS:
若是設置成True(默認狀況),Flask-SQLAlchemy 將會追蹤對象的修改而且發送信號。這須要額外的內存, 若是沒必要要的能夠禁用它。若是你不顯示的調用它,在最新版的運行環境下,會顯示警告。
(7)db = SQLAlchemy(app)
SQLAlchemy函數,將剛剛建立的Flask框架,與工程所須要使用的數據庫綁定到一塊兒,以便實現工程與數據庫鏈接,實現數據操做。
(8)db_init()函數
手動建立函數,以便初始化數據庫
以上就是配置database.py的一些說明,但如今還遠遠不夠,由於當前工程的數據庫在建立以後只是單純的一個空數據庫,不包含任何數據表。
那怎麼建立數據表呢,工程下須要一個映射表,以便將表格映射到數據庫中,以達到建立表格的做用。
3.建立映射表
以下爲一段建立最簡單的User數據表的代碼。
from database import db class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True) email = db.Column(db.String(120), unique=True) def __init__(self, username, email): self.username = username self.email = email def __repr__(self): return '<User %r>' % self.usernam
仍然是逐句解釋
(1)from database import db
將剛剛建立的SQLAlchemy應用引用到當前文件,以便將映射表映射到數據庫中,以便對於數據表的建立修改以及更新刪除。
(2)db.Model
上邊提到,當工程文件不提供映射表時將建立一個空的數據庫文件。繼承db.Model類,將咱們當前建立的映射表和數據庫db綁定在一塊兒。此時工程文件調用create_all函數後,會自動將綁定後的映射表文件建立在數據庫文件中。
若是想探究詳細綁定關係,請應用純SQlAlchemy庫,而不是flask-sqlalchemy庫,以前調到了flask-sqlalchemy是簡化版的SQLAlchemy,隱藏了許多細節,深刻研究請轉至SQLAlchemy官方文檔查看應用細節。
(3)db.Column
建立映射表字段,如下爲最多見的類型
Integer | 存儲整數 |
String(size) | 存儲有長度的字符串 |
Text | 存儲較長的unicode文本 |
DateTime | 存儲時間類型數據 |
Float | 存儲浮點值 |
Boolean | 存儲布爾值 |
PickleType | 存儲一個python對象 |
LargeBinary | 存儲一個任意大的二進制數據 |
primary_key=True設置當前字段爲主鍵
uniqu=True設置當前字段不可重複
固然也能夠設置主鍵外鍵,在本文中只建立了一張數據表,在之後的文章中將說明此操做。
(4)__init__函數
爲映射表的構造函數,通常用來初始變量,配置相關數據時使用
(5)__repr__函數
爲之後調試輸出提供接口
4.修改database.py
將下面的代碼添加到database.py的底部
from model import User
Q:爲何添加到底部呢?
A:若是你添加到頭部引用model中的User,此時User類已經被引用並建立。有沒有發現一個問題,User類繼承了db.Model類,那麼此時User類建立的時候沒法找到db這個參數,由於db參數尚未建立。
from flask import Flask from flask_sqlalchemy import SQLAlchemy import os from model import User
上邊的就是錯誤的例子,當你引用User類時,此時db對象尚未被建立,因此調用db_init()函數時會顯示ImportError: cannot import name 'User'
from flask import Flask from flask_sqlalchemy import SQLAlchemy import os ... db = SQLAlchemy(app) ... from model import User
上邊的僞代碼就是正確的寫法,引用User類的時機至少要等到db對象建立結束後才能引用。爲何放在底部呢?爲了調整文件結構,使代碼看起來不是很亂,放在其餘處也不要緊,但請注意如下兩點:
(1)若是你打算在該文件引用User類,請保證全局引用。
(2)不管發在哪裏,至少要在db = SQLAlchemy(app)執行後,生成db對象才能進行引用,不然會致使model.py文件執行錯誤。
至此,映射表文件建立成功。
4.建立數據庫
將以上配置結束後,能夠調用db_init()函數建立數據庫了。
還記得以前配置的虛擬python運行環境麼,在虛擬環境下輸入python,進入python指令模式進行建立
此時,工程文件夾根目錄已經生成了內置的sqlite數據庫文件test.db
四.SQLAlchemy下的數據庫操做
1.insert
添加4個用戶,將database.py中的User和db引用到文件中,此處必須引用database中的User,若是引用model中的User會形成循環引用,由於model.py中引用了database模塊中的db變量
from database from User,db
u1 = User(username= 'john', email = 'john@example.com') u2 = User(username= 'susan', email = 'susan@example.com') u3 = User(username= 'mary', email = 'mary@example.com') u4 = User(username= 'david', email = 'david@example.com') db.session.add(u1) db.session.add(u2) db.session.add(u3) db.session.add(u4) db.session.commit()
(1)對象 = User(字段1='值1',字段2='值2')
至關於SQL操做INSERT INTO User VALUES(字段1='值1',字段2='值2'),並將該SQL語句賦值到一個對象上
(2)db.session.add()
將對於數據庫的操做保存在緩存中,既然是保存到緩存中,那麼該數據庫語句尚未提交到數據庫中
(3)db.session.commit()
commit()和數據庫中的commit指令同樣,將數據庫操做提交到數據庫中。
2.select
查詢全部用戶信息,並輸出結果
from database import User, db for user in User.query.all(): print(user.id, user.name, user.email)
如下是運行產生的結果
(1)精確查詢
查詢用戶名爲susan的用戶郵箱
from database import User, db u = User.query.filter_by(username='susan').first() print(u.email)
(2)模糊查詢
查詢郵箱以example.com結尾的用戶,輸出用戶名及郵箱
from database import User, db for user in User.query.filter(User.email.ilike('%example.com')).all(): print(user.username, user.email)
如下是運行產生的結果
PS:將查詢出的結果按照正序或者逆序排序請使用,以username爲例order_by(User.username)正序,order_by(User.username.desc())逆序
3.update
更新操做和查詢操做有交集,請看如下代碼示例,將john的郵箱修改成john@example.vip.com
from database import User, db u = User.query.filter_by(username='john').first() u.email = 'john@example.vip.com' db.session.add(u) db.session.commit()
解釋起來就是首先將對象查詢出來,而後將修改的字段賦值,並將查詢出的對象提交到數據庫,這樣更新操做就結束了。
4.delete
將david用戶刪除
from database import User, db u = User.query.filter_by(username='john').first() db.session.delete(u) db.session.commit()
調用delete()函數,將數據傳入db對象,並提交到數據庫中。
五.單體測試框架測試
對本文提到的操做進行單體測試。(test.py文件代碼以下)
import unittest from database import User, db class TestCase(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def test_db(self): u1 = User.query.filter_by(username='john').first() u2 = User.query.filter_by(username='susan').first() u3 = User.query.filter_by(username='mary').first() u4 = User.query.filter_by(username='david').first() assert u1.email == 'john@example.vip.com' assert u2.email == 'susan@example.com' assert u3.email == 'mary@example.com' assert u4.email == 'david@example.com' u5 = User(username='Alima', email='Alima@example.com') db.session.add(u5) db.session.commit() u = User.query.filter_by(username='Alima').first() assert u.email == 'Alima@example.com' u5.email = 'Alima@example.vip.com' db.session.add(u5) db.session.commit() u = User.query.filter_by(username='Alima').first() assert u.email == 'Alima@example.vip.com' db.session.delete(u5) db.session.commit() u = User.query.filter_by(username='Alima').first() assert u == None if __name__ == '__main__': unittest.main()
執行test.py,運行結果:
顯示OK,單體測試結束。
以上就是基本的flask-SQLAlchemy初級使用實例說明,歡迎探討轉載及引用參考,大家的迴應是個人動力。
若是文中存在錯誤或是某個地方說的不夠精確,勞煩批評指出。
以上,辛苦了。
參考資料:
[1] [sogou][搜狗百科][ORM] http://baike.sogou.com/v75834.htm?fromTitle=ORM
[2] [csdn][seanb][Flask中路由使用解析] http://blog.csdn.net/seanb/article/details/51454833
[3] [flask][flask-sqlalchemy][官方文檔] http://flask-sqlalchemy.pocoo.org/2.1/
*本文爲Alima原創,若是轉載請聯繫筆者,轉載註明格式[轉載][博客園][Alima][關於flask-SQLAlchemy的初級使用教程],並在文尾註明本文連接,多謝合做。
*非法轉載及非法抄襲博文將依照網絡著做權流程辦理,請尊重做者勞動成果