[python][flask][flask-SQLAlchemy]關於flask-SQLAlchemy的初級使用教程


鑒於網上關於flask-SQLAlchemy的實例使用教程參差不齊,於此寫下工作學習過程中的使用過程,以便分享交流。

對於python關於flask有一定了解的高端玩家來說,請轉至flask官方開發文檔

 

一.安裝(install)

需要有安裝python的PC一台,介於windows系統用戶比較多,本文章使用的是windows下開發。

1.創建虛擬

為每一個工程創建一個獨立的python運行環境是我們所需要的,python提供了virtualenv,可以為我們提供這個特殊的需求。

配置virtualenv環境

windows環境下運行cmd.exe,使用管理員權限運行。

 pip install virtualenv

筆者使用的python版本是3.5.2,該版本中自動配置了pip應用,使用pip指令可以很方便的下載到你所需要的python拓展庫。  

安裝成功后會出現successfully installed virtualenv字樣。

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的初級使用教程],並在文尾注明本文鏈接,多謝合作。

*非法轉載及非法抄襲博文將依照網絡著作權流程辦理,請尊重作者勞動成果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM