Python??Flask框架操作數(shù)據(jù)庫(kù)的方法
簡(jiǎn)介
SQLAlchamy 是 Python 中一個(gè)通過(guò) ORM 操作數(shù)據(jù)庫(kù)的框架
SQLAlchemy(對(duì)象關(guān)系映射器)提供了一種方法,用于將用戶定義的Python類(lèi)與數(shù)據(jù)庫(kù)表相關(guān)聯(lián),并將這些類(lèi)(對(duì)象)的實(shí)例與其對(duì)應(yīng)表中的行相關(guān)聯(lián)。
簡(jiǎn)單理解: 創(chuàng)建一個(gè)類(lèi),一個(gè)類(lèi)對(duì)應(yīng)了一個(gè)數(shù)據(jù)庫(kù)中的一張表,類(lèi)的屬性名對(duì)應(yīng)了表中的字段名,這個(gè)類(lèi)稱為映射類(lèi)
SQLAlchemy本身無(wú)法操作數(shù)據(jù)庫(kù),其必須使用 pymsql 等第三方插件,從而實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的操作,如:mysql數(shù)據(jù)庫(kù)
mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
使用
flask_sqlalchamy
Flask 中最方便用的數(shù)據(jù)庫(kù)框架是 flask_sqlalchamy,是對(duì) SQLAlchamy 在 Flask 中的擴(kuò)展,它主要在于簡(jiǎn)化Flask 中 sqlalchamy的使用
安裝
pip install flask_sqlalchemy
初始化
為了方便管理數(shù)據(jù)庫(kù)相關(guān)的配置項(xiàng),flask_sqlalchamy 中采用app.config進(jìn)行相關(guān)屬性配置
配置變量的名稱必須使用大寫(xiě),寫(xiě)入配置的語(yǔ)句一般會(huì)放到擴(kuò)展類(lèi)實(shí)例化語(yǔ)句之前
配置項(xiàng) | 說(shuō)明 |
SQLALCHEMY_DATABASE_URI | 數(shù)據(jù)庫(kù)的鏈接地址 |
SQLALCHEMY_BINDS | 訪問(wèn)多個(gè)數(shù)據(jù)庫(kù)時(shí),用于設(shè)置數(shù)據(jù)庫(kù)鏈接池地址 |
SQLALCHEMY_ECHO | 是否打印底層執(zhí)行的SQL語(yǔ)句 |
SQLALCHEMY_RECORD_QUERIES | 是否記錄執(zhí)行的查詢語(yǔ)句,用于慢查詢分析 |
SQLALCHEMY_TRACK_MODIFICATIONS | 是否追蹤數(shù)據(jù)庫(kù)變化 |
SQLALCHEMY_ENGINE_OPTIONS | 設(shè)置針對(duì) sqlalchemy本體的配置項(xiàng) |
設(shè)置數(shù)據(jù)庫(kù)鏈接
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # 設(shè)置數(shù)據(jù)庫(kù)鏈接地址 app.config['SQLALCHEMY_DATABASE_URI']='mysql+pymysql://root:123456@127.0.0.1:3306/test' # 設(shè)置顯示底層執(zhí)行的sql語(yǔ)句 app.config['SQLALCHEMY_ECHO'] = True # 初始化組件對(duì)象,關(guān)聯(lián)flask應(yīng)用 db = SQLAlchemy(app)
構(gòu)建模型
模型簡(jiǎn)單來(lái)說(shuō)就是數(shù)據(jù)庫(kù)中的一張表定義,需要有名稱,字段,在 Python 中用一個(gè)類(lèi)來(lái)表示,由于需要和數(shù)據(jù)庫(kù)的表對(duì)應(yīng),模型必須繼承自 SQLAlchamy 的 Model 類(lèi)
from flask import Flask from flask_sqlalchemy import SQLAlchemy import datetime app = Flask(__name__) # 設(shè)置數(shù)據(jù)庫(kù)鏈接地址 app.config['SQLALCHEMY_DATABASE_URI']='mysql+pymysql://root:123456@127.0.0.1:3306/test' # 設(shè)置顯示底層執(zhí)行的sql語(yǔ)句 app.config['SQLALCHEMY_ECHO'] = True # 初始化組件對(duì)象,關(guān)聯(lián)flask應(yīng)用 db = SQLAlchemy(app) # 構(gòu)建模型類(lèi) class User(db.Model): # 設(shè)置表名,表名默認(rèn)為類(lèi)名小寫(xiě) __tablename__ = 'user' id = db.Column(db.Integer,primary_key=True) # 設(shè)置主鍵,默認(rèn)自增 name = db.Column(db.String(20)) age = db.Column(db.Integer,default=20) #設(shè)置默認(rèn)值 createtime=db.Column(db.DateTime()) def __repr__(self): # 自定義 交互模式 & print() 的對(duì)象打印 return "(%s, %s, %s, %s)" % (self.id, self.name, self.age,self.createtime) if __name__ == '__main__': app.run(debug=True)
__repr__
方法定義了一個(gè)對(duì)象的比較易讀的顯式方式
常用字段類(lèi)
字段類(lèi)型 | 說(shuō)明 |
---|---|
db.Integer | 整數(shù) |
db.String(size) | 字符串 size 為字符串長(zhǎng)度 |
db.DateTime | 日期時(shí)間 |
db.Date | 日期 |
db.Text | 長(zhǎng)文本,可以存放 CLOB (二進(jìn)制數(shù)據(jù)) |
db.Float | 浮點(diǎn)數(shù)字 |
db.Boolean | 布爾值 |
常用字段選項(xiàng)
字段類(lèi)型 | 說(shuō)明 |
---|---|
primary_key | 設(shè)置表的主鍵,默認(rèn)自增 |
unique | 設(shè)置唯一索引 |
nullable | 非空約束 |
default | 設(shè)置默認(rèn)值 |
index | 創(chuàng)建索引 |
創(chuàng)建庫(kù)表
@app.route("/initDB") def init_db(): # 刪除所有繼承睡在db.Model的表 db.drop_all() # 創(chuàng)建所有繼承自 db.Model的表 db.create_all() return "initdb"
注:db.drop_all() 和 db.create_all() 放在 main中不啟作用,所以單獨(dú)寫(xiě)一個(gè)方法進(jìn)行初始化。
一般庫(kù)表的創(chuàng)建與應(yīng)用都是分開(kāi)的,單獨(dú)創(chuàng)建庫(kù)表,沒(méi)必要將此類(lèi)語(yǔ)句寫(xiě)在應(yīng)用中
數(shù)據(jù)操作
增加數(shù)據(jù)
@app.route("/add") def add(): # 添加數(shù)據(jù) user1 = User(name='zhao', age=33, createtime=datetime.datetime.now()) # 將模型添加到會(huì)話中 db.session.add(user1) # 添加多條記錄 # db.session.add_all([user1,user2,user3]) # 提交會(huì)話, sqlalchemy會(huì)自動(dòng)創(chuàng)建隱式事務(wù),失敗會(huì)自動(dòng)回滾 db.session.commit() return "add"
注:
- sqlalchemy會(huì)自動(dòng)創(chuàng)建事務(wù),并將數(shù)據(jù)的操作都包含在一個(gè)事務(wù)中,提交會(huì)話就會(huì)提交事務(wù)
- session 是一個(gè)與數(shù)據(jù)庫(kù)通信的會(huì)話,是 SQLAlchamy 框架與數(shù)據(jù)庫(kù)交互的代理
- 可以調(diào)用 session.rollback() 回滾掉未提交的變化
查詢數(shù)據(jù)
簡(jiǎn)單查詢
@app.route("/query") def query(): # 查詢所有用戶數(shù)據(jù), 返回User列表, data = User.query.all() for item in data: print(item.name,item.age) # 查詢有多少個(gè)用戶,返回結(jié)果數(shù) data = User.query.count() print(data) # 查詢第1個(gè)用戶 , 返回User對(duì)象 data = User.query.first() print(data) # 查詢id為4的用戶, 返回User對(duì)象 data = User.query.get(4) print(data) return "query"
條件過(guò)濾查詢
@app.route("/query2") def query2(): # 查詢 name 等于 zhao 的記錄集中第一條記錄 data = User.query.filter(User.name =='zhao').first() # 查詢 name 不等于 zhao 的所有記錄 data = User.query.filter(User.name != 'zhao').all() # 前模糊查詢 data = User.query.filter(User.name.like("%zhao")).all() print(data) # 查詢名字以 zhao 開(kāi)頭的用戶 data = User.query.filter(User.name.startswith('zhao')).all() # 查詢名字是 zhao,并且年齡是22歲的用戶 from sqlalchemy import and_ data = User.query.filter(and_(User.name=='zhao', User.age==22)).all() # 查詢名字是 zhao或者h(yuǎn)ong的用戶 from sqlalchemy import or_ data = User.query.filter(or_(User.name=='zhao', User.name=='hong')).all() # 查詢id為[1, 2, 3]的用戶 data = User.query.filter(User.id.in_([1, 2, 3])).all() # 分頁(yè)查詢 # 所有用戶先按年齡從小到大, 再按id從大到小排序, 取前5個(gè) data = User.query.order_by(User.age, User.id.desc()).limit(5).all() # 分頁(yè)查詢, 每頁(yè)1個(gè), 查詢第2頁(yè)的數(shù)據(jù) paginate(頁(yè)碼, 每頁(yè)條數(shù)) pn = User.query.paginate(page=2, per_page=1) print("總頁(yè)數(shù):"+str(pn.pages)+" 當(dāng)前頁(yè)碼:"+str(pn.page)+"當(dāng)前頁(yè)的數(shù)據(jù):"+ str(pn.items)+" 總條數(shù):"+str(pn.total)) # 分組查詢 # 查詢每個(gè)年齡的人數(shù) select age, count(name) from t_user group by age 分組聚合 from sqlalchemy import func data = db.session.query(User.age, func.count(User.id).label("count")).group_by(User.age).all() return "query2"
常用查詢方法
方法名稱 | 說(shuō)明 |
---|---|
all() | 返回所有查詢記錄的列表 |
first() | 返回查詢的第一條記錄,如果未找到,則返回None |
get(id) | 傳入主鍵值作為參數(shù),返回指定主鍵值的記錄,如果未找到,則返回None |
count() | 返回查詢結(jié)果的數(shù)量 |
paginate() | 返回一個(gè)Pagination對(duì)象,可以對(duì)記錄進(jìn)行分頁(yè)處理 |
更新數(shù)據(jù)
@app.route("/update") def update(): # 更新用戶年齡為44,條件是:用戶名=zhao # 相當(dāng)于:update user set age = 44 where name = 'zhao'; User.query.filter(User.name == 'zhao').update({'age': 44}) # 提交會(huì)話 db.session.commit() return "update"
刪除數(shù)據(jù)
@app.route("/del") def delete(): # 刪除id=1的用戶 # 相當(dāng)于:delete from user where id=1 User.query.filter(User.id == 1).delete() # 提交會(huì)話 db.session.commit() return "del"
多表關(guān)聯(lián)查詢
連接查詢
開(kāi)發(fā)中有 聯(lián)表查詢需求 時(shí), 一般會(huì)使用 join連接查詢
db.session.query(主表模型字段1, 主表模型字段2, 從表模型字段1, xx.. ).join(從表模型類(lèi), 主表模型類(lèi).主鍵 == 從表模型類(lèi).外鍵)
示例
from flask import Flask from flask_sqlalchemy import SQLAlchemy import datetime app = Flask(__name__) # 設(shè)置數(shù)據(jù)庫(kù)鏈接地址 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/test' # 設(shè)置顯示底層執(zhí)行的sql語(yǔ)句 app.config['SQLALCHEMY_ECHO'] = True # 初始化組件對(duì)象,關(guān)聯(lián)flask應(yīng)用 db = SQLAlchemy(app) # 構(gòu)建模型類(lèi) class User(db.Model): # 設(shè)置表名,表名默認(rèn)為類(lèi)名小寫(xiě) __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) # 設(shè)置主鍵,默認(rèn)自增 name = db.Column(db.String(20)) age = db.Column(db.Integer, default=20) # 設(shè)置默認(rèn)值 createtime = db.Column(db.DateTime()) def __repr__(self): # 自定義 交互模式 & print() 的對(duì)象打印 return "(%s, %s, %s, %s)" % (self.id, self.name, self.age, self.createtime) class Address(db.Model): __tablename__ = 'address' id = db.Column(db.Integer, primary_key=True) detail = db.Column(db.String(20)) user_id = db.Column(db.Integer) # 定義外鍵 if __name__ == '__main__': app.run(debug=True) @app.route("/") def index(): return "index" @app.route("/query") def query(): """ 查詢多表數(shù)據(jù) 需求: 查詢姓名為"hong" 的用戶id和地址信息""" # sqlalchemy的join查詢 # 相當(dāng)于:SELECT user.id AS user_id, address.detail AS address_detail # FROM user INNER JOIN address ON user.id = address.user_id data = db.session.query(User.id, Address.detail).join(Address, User.id == Address.user_id).filter( User.name == 'hong').all() for item in data: print(item.detail, item.id) return "query"
到此這篇關(guān)于Python Flask的數(shù)據(jù)庫(kù)操作的文章就介紹到這了,更多相關(guān)Python Flask操作數(shù)據(jù)庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python3.7 讀取音頻根據(jù)文件名生成腳本的代碼
這篇文章主要介紹了Python3.7 讀取音頻根據(jù)文件名生成字幕腳本的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04python自制簡(jiǎn)易mysql連接池的實(shí)現(xiàn)示例
本文主要介紹了python自制簡(jiǎn)易mysql連接池的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11python 打印出所有的對(duì)象/模塊的屬性(實(shí)例代碼)
下面小編就為大家?guī)?lái)一篇python 打印出所有的對(duì)象/模塊的屬性(實(shí)例代碼)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09Python中模塊(Module)和包(Package)的區(qū)別詳解
這篇文章主要介紹了Python中模塊(Module)和包(Package)的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08python利用datetime模塊計(jì)算程序運(yùn)行時(shí)間問(wèn)題
這篇文章主要介紹了python利用datetime模塊計(jì)算程序運(yùn)行時(shí)間,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02基于wxPython的GUI實(shí)現(xiàn)輸入對(duì)話框(2)
這篇文章主要為大家詳細(xì)介紹了基于wxPython的GUI實(shí)現(xiàn)輸入對(duì)話框的第二篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02Python編程使用PyQt5制作動(dòng)態(tài)鐘表示例
本篇文章將用 Python 同時(shí)繪制兩種類(lèi)型的表;一個(gè)是上面提到的含有時(shí)、分、秒針的鐘表(為了方便,下面統(tǒng)稱為老式鐘表),一個(gè)是電子表,最終運(yùn)行效果文中如下呈現(xiàn)2021-10-10