佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > Flask使用SQLAlchemy實現(xiàn)持久化數(shù)據(jù)

Flask使用SQLAlchemy實現(xiàn)持久化數(shù)據(jù)

熱門標簽:呼叫中心市場需求 鐵路電話系統(tǒng) 網(wǎng)站文章發(fā)布 美圖手機 智能手機 銀行業(yè)務 服務器配置 檢查注冊表項

項目引入flask-sqlalchemy

首先,安裝flask-sqlalchemy擴展:

$pip install flask-sqlalchemy

然后,在項目中導入SQLAlchemy類,并實例化應用程序使用的數(shù)據(jù)庫(以mysql為例):

from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://account:password@hostname/database'
db = SQLAlchemy(app)

db對象是SQLAlchemy類的實例,表示程序使用的數(shù)據(jù)庫,同時還獲得了Flask-SQLAlchemy提供的所有功能。

ORM簡介及模型定義

在Python中,可以使用數(shù)據(jù)庫相應的包直接操作數(shù)據(jù)庫,如PyMySQL操作MySQL數(shù)據(jù)庫,還有一些數(shù)據(jù)庫抽象層代碼包供選擇,如這里要討論的SQLAlchemy。該抽象包直接處理高等級的Python對象,而不用處理如表這樣的數(shù)據(jù)庫實體。
抽象層,就是所謂的對象關系映射(ORM),其最大的優(yōu)勢就是:能在用戶不知覺的情況下把高層的面向?qū)ο蟛僮鬓D(zhuǎn)換成低層的數(shù)據(jù)庫指令,極大簡化代碼編寫。SQLAlchemy就是已與Flask很好集成的更高層抽象例子,其還支持多種關系型數(shù)據(jù)庫引擎。

基于SQLAlchemy的模型定義:

class Roles(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    users = db.relationship('Users', backref='role')

class Users(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

__tablename__定義在數(shù)據(jù)庫中使用的表名;

db.Column類構(gòu)造函數(shù)的第1個參數(shù)是數(shù)據(jù)庫表列(也是模型屬性)的類型,其余的參數(shù)指定屬性(數(shù)據(jù)庫表列)的配置選項。

2.1 常用的SQLAlchemy列類型

類型名 Python類型 說明
Integer int 普通整數(shù),一般32位
SmallInteger int 取值范圍小的整數(shù),一般16位
BigInteger int或long 不限制精度的整數(shù)
Float float 浮點數(shù)
String str 變長字符串
Boolean bool 布爾值
Date datetime.date 日期
Time datetime.time 時間
DateTime datetime.datetime 日期和時間
Text str 變長字符串,對較長或不限長度的字符串做了優(yōu)化
Numeric decimal.Decimal 定點小數(shù)

2.2 常用的SQLAlchemy列選項

選項名 說明
primary_key 如果設為True,這列就是表的主鍵
unique 如果設為True,這列不允許重復值
index 如果設為True,為該列創(chuàng)建索引,提升查詢效率
nullable 如果設為True,這列允許null值,如果設為false,不允許為空
default 為這列定義默認值

表關系類型及編碼實現(xiàn)

關系型數(shù)據(jù)庫使用關系把不同表中的行聯(lián)系起來。以上述模型定義代碼為例,假設角色對用戶是一對多的關系(即1個角色可屬于多個用戶,而每個用戶只能有1個角色)。

一對多關系(多對一關系)

在“多”的一方,使用外鍵定義關系
如在Users模型中,定義role_id列為外鍵,給db.Column構(gòu)造函數(shù)傳遞db.ForeignKey()參數(shù),并將roles.id作為db.ForeignKey()的參數(shù),其表明role_id列的值是roles表中行的id值。
在“一”的一方,基于面向?qū)ο蟮囊暯莿?chuàng)建代表實例(記錄或行)的屬性,如上述的users = db.relationship(‘Users', backref=‘role')
db.relationship()的第1個參數(shù)表明這個關系的另一端是哪個模型,backref參數(shù)向Users模型添加一個role屬性,從而定義反向關系。通過這一屬性(role)可以替代role_id訪問Roles模型,此時將獲取的是模型對象,而不是外鍵的值。
如何理解上述這段話,可以從下面2句代碼加深:

 users = inst_role.users
 user_role = user.role

通過第1句代碼,可以直接獲得特定角色實例(inst_role)相對應的所有users對象,且是以列表形式返回。
通過第2句代碼,可以通過user實例直接獲得該user所對應的role對象(1行記錄,而不是Users模式定義的role_id字段值)。

一對一關系

要定義一對一的關系,只需基于一對多的模型定義基礎上,給db.relationship()函數(shù)多傳一個關鍵字表示關系選項:
users = db.relationship(‘Users', backref=‘role', userlist=False)
一對多與一對一在編碼時,有個點需特別注意:當通過“一”的實例(db.relationship定義方)獲取多的一方的對象時:

  • 一對多:users = inst_role.users返回的是對象列表
  • 一對一:users = inst_role.users返回的就是對象,而非列表

多對多關系

Pending…

數(shù)據(jù)庫基本操作

在Flask-SQLAlchemy中,對數(shù)據(jù)庫所做的改動均是通過數(shù)據(jù)庫“會話”進行管理的,會話用db.session表示。如需用db.session.commit()提交對記錄的修改,始終把數(shù)據(jù)庫相關改動放在會話中提交,可避免因部分更新異常導致數(shù)據(jù)庫中數(shù)據(jù)的不一致性。

插入

    admin_role = Roles(name='Admin')
    mod_role = Roles(name='Moderator')
    john = Users(username='liyu', role=admin_role)
    david = Users(username='liji', role=admin_role)
    db.session.add(admin_role)
    db.session.add(mod_role)
    db.session.add(john)
    db.session.add(david)
    db.session.commit()

前4行代碼,實例化2種角色及2個用戶對象(映射至數(shù)據(jù)庫即是給記錄的字段賦值)
5~7行代碼就是將新增角色及用戶操作放在了1個session中,最后再統(tǒng)一提交(commit),可防止因其中某條語句異常而更新部分從而導致數(shù)據(jù)的不一致性。該操作就是將多個原子操作組成一個事務,如果某條更新失敗就會導致整個會話失效。
5~7行還可簡寫成: db.session.add([admin_role, mod_role, john, david])

更新

在Flask-SQLAlchemy中,一條記錄表示為一個對象;記錄的字段表示為對象的屬性,因此要更新字段值,實際上就是對對象的屬性賦值:

admin_role.name = 'Administrator'
db.session.add(admin_role)
db.session.commit()

查詢

查詢表中所有記錄:模式.query.all()

eg. Roles.query.all()

使用過濾器進行更精確查詢

過濾器 說明
filter 把過濾器添加到原查詢上
filter_by 把等值過濾器添加到原查詢上
limit 使用指定的值限制原查詢返回的結(jié)果數(shù)量
offset 偏移原查詢返回的結(jié)果
order_by 根據(jù)指定條件對原查詢結(jié)果進行排序
group_by 根據(jù)指定條件對原查詢結(jié)果進行分組

2.1 filter與filter_by區(qū)別

2.1.1 語法區(qū)別

filter需要用“類名.屬性名”且需用==比較,而filter_by直接用屬性名,比較用=

users = Users.query.filter(Users.id == 1).all()
users =  Users.query.filter_by(id = 1).all()

2.1.2 組合查詢

filter不支持組合查詢,只能連續(xù)用filter來實現(xiàn),而filter_by支持組合查詢(下面2條語句效果一樣)

users = Users.query.filter(Users.id == 1).filter(Users.username == 'xxx').all()
users =  Users.query.filter_by(id = 1, username='xxx').all()
# filter_by也支持連續(xù)使用

注:如果要查看SQLAlchemy為查詢生成的原生SQL查詢語句,只需把query對象轉(zhuǎn)換成字符串: str(Users.query.filter_by(role=admin_role))

刪除

執(zhí)行查詢

在查詢上應用指定的過濾器后,通過調(diào)用all()觸發(fā)執(zhí)行查詢,常見的觸發(fā)執(zhí)行方法有: 

方法 說明
all() 查詢所有結(jié)果
first() 返回查詢的第1個結(jié)果,沒有返回None
get() 返回指定主鍵對應的行,沒有返回None
count() 返回查詢結(jié)果的數(shù)量
first_or_404() 返回查詢的第1個結(jié)果,如果沒有結(jié)果,則終止請求,返回404錯誤響應
get_or_404() 返回指定主鍵對應的行,如果沒找到指定的主鍵,則終止請求,返回404錯誤響應
paginate() 返回一個paginate對象

4.1 一對多

4.1.1 從“一”獲取對應的所有多端對象

users = inst_role.users //直接通過角色對象的users屬性獲取所有屬于該角色的用戶對象
role = inst_user.role  //直接通過用戶實例的role屬性獲取該用戶所屬的角色對象,注意這里獲取的是角色對象,而不僅是角色ID

注:inst_role.users獲取對象時,隱含了調(diào)用all()方法觸發(fā)執(zhí)行,但如果像加一些過濾器(如排序),則需要在db.relationship中添加lazy='dynamic'關鍵字參數(shù)。然后即可引入過濾器:inst_role.users.order_by(Users.username)

4.2 多對多

Pending…

在Flask-SQLAlchemy中,刪除數(shù)據(jù)庫記錄,可映射至刪除代表該記錄的對象:

db.session.delete(mod_role)
db.session.commit()

參考資料

到此這篇關于Flask使用SQLAlchemy實現(xiàn)持久化數(shù)據(jù)的文章就介紹到這了,更多相關Flask SQLAlchemy持久化數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Flask中sqlalchemy模塊的實例用法
  • flask的orm框架SQLAlchemy查詢實現(xiàn)解析
  • Python使用Flask-SQLAlchemy連接數(shù)據(jù)庫操作示例
  • Python利用flask sqlalchemy實現(xiàn)分頁效果
  • Python的Flask框架中使用Flask-SQLAlchemy管理數(shù)據(jù)庫的教程
  • 在Python程序和Flask框架中使用SQLAlchemy的教程
  • Python的Flask框架中SQLAlchemy使用時的亂碼問題解決
  • 在Python的Flask框架下使用sqlalchemy庫的簡單教程
  • Flask SQLAlchemy一對一,一對多的使用方法實踐
  • flask中使用SQLAlchemy進行輔助開發(fā)的代碼

標簽:河南 沈陽 樂山 長治 上海 滄州 新疆 紅河

巨人網(wǎng)絡通訊聲明:本文標題《Flask使用SQLAlchemy實現(xiàn)持久化數(shù)據(jù)》,本文關鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權(quán)與本站無關。
  • 相關文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    鄄城县| 双辽市| 马边| 石狮市| 九台市| 大同县| 苍溪县| 无棣县| 冀州市| 石屏县| 章丘市| 洛扎县| 丘北县| 晋州市| 石楼县| 灵丘县| 文化| 南木林县| 电白县| 张北县| 湄潭县| 佳木斯市| 银川市| 丹寨县| 民和| 新余市| 沁水县| 开封市| 甘洛县| 西乌珠穆沁旗| 大同县| 富顺县| 平安县| 集贤县| 丘北县| 新晃| 克拉玛依市| 连南| 车致| 屏山县| 霸州市|