摘要:初始化和配置對象關系映射。的則需要在中聲明。例如配置信息中指出是可以綁定多個數(shù)據(jù)庫引擎。是通過解決一對多的關系。將會返回學院學生人數(shù)將會返回學生的學院信息的類實例。處理關系對象查詢中有詳細的說明。
初始化和配置
ORM(Object Relational Mapper) 對象關系映射。指將面對對象得方法映射到數(shù)據(jù)庫中的關系對象中。
Flask-SQLAlchemy是一個Flask擴展,能夠支持多種數(shù)據(jù)庫后臺,我們可以不需要關心SQL的處理細節(jié),操作數(shù)據(jù)庫,一個基本關系對應一個類,而一個實體對應類的實例對象,通過調(diào)用方法操作數(shù)據(jù)庫。Flask-SQLAlchemy有很完善的文檔。
Flask-SQLAlchemy是通過URL指定數(shù)據(jù)庫的連接信息的。
初始化的兩種方法如下(以連接Mysql數(shù)據(jù)庫為例):
from flask_sqlalchemy import SQLAlchemy from flask import FLask app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:12345@localhost/test" db = SQLAlchemy(app)
或者
from flask_sqlalchemy import SQLAlchemy from flask import FLask db = SQLAlchemy() def create_app(): app = Flask(__name__) db.init_app(app) return app
兩者的區(qū)別在于:第一種不需要啟動flask的app_context;但是第二種方法則需要,因為可能會創(chuàng)建多個Flask應用,但是我的理解是一般地開發(fā)時,F(xiàn)lask實例是延遲創(chuàng)建的,因為在運行時難以修改配置信息,這種方法符合這種情況。
Flask-SQLAlchemy的則需要在Flask.config中聲明。更多詳細信息需要查配置。例如配置信息中指出SQLAlchemy是可以綁定多個數(shù)據(jù)庫引擎。再例如:在新浪SAE云平臺開發(fā)個人博客時遇到gone away這種問題就需要添加SQLALCHEMY_POOL_RECYCLE信息,新浪開發(fā)者文檔中有說明。
SQLAlchemy是如何處理對象到關系的?實例來自于數(shù)據(jù)庫系統(tǒng)概論內(nèi)容。
簡單實例創(chuàng)建學生students表
class Student(db.Model): __tablename__ = "students" #指定表名 sno = db.Column(db.String(10), primary_key=True) sname = db.Column(db.String(10)) sage = db.Column(db.Integer)
API文檔說明創(chuàng)建對象需要繼承db.Model類關聯(lián)數(shù)據(jù)表項,db.Model類繼承Query類提供有數(shù)據(jù)查詢方法;__tablename__指定數(shù)據(jù)庫的表名,在Flask-SQLAlchemy中是可省的。Column指定表字段。
SQLAlchemy支持字段類型有:
類型名 | python類型 | 說明 |
---|---|---|
Integer | int | 普通整數(shù),32位 |
Float | float | 浮點數(shù) |
String | str | 變長字符串 |
Text | str | 變長字符串,對較長字符串做了優(yōu)化 |
Boolean | bool | 布爾值 |
PickleType | 任何python對象 | 自動使用Pickle序列化 |
來源于Simple Example,F(xiàn)lask Web開發(fā)有更詳細的內(nèi)容。
其余的參數(shù)指定屬性的配置選項,常用的配置選項如下:
選項名 | 說明 |
---|---|
primarykey | 如果設為True,表示主鍵 |
unique | 如果設為True,這列不重復 |
index | 如果設為True,創(chuàng)建索引,提升查詢效率 |
nullable | 如果設為True,允許空值 |
default | 為這列定義默認值 |
如使用default默認time屬性如下:
time = db.Column(db.Date, default=datetime.utcnow)
說明default可以接受lambda表達式。
一對多按創(chuàng)建單張表的方法,創(chuàng)建學院Deptment表
class Deptment(db.Model): __tablename__ = "deptments" dno = db.Column(db.Integer, primary_key=True) dname = Sname = db.Column(db.String(10),index=True)
學院和學生是一對多的關系。Flask-SQLAlchemy是通過db.relationship()解決一對多的關系。在Dept中添加屬性,代碼如下:
class Deptment(db.Model): ... students = db.relationship("Student", backref="dept") class Student(db.Model): ... dept_no = db.Column(db.Integer, db.ForeignKey("deptments.dno"))
表的外鍵由db.ForeignKey指定,傳入的參數(shù)是表的字段。db.relations它聲明的屬性不作為表字段,第一個參數(shù)是關聯(lián)類的名字,backref是一個反向身份的代理,相當于在Student類中添加了dept的屬性。例如,有Deptment實例dept和Student實例stu。dept.students.count()將會返回學院學生人數(shù);stu.dept.first()將會返回學生的學院信息的Deptment類實例。一般來講db.relationship()會放在一這一邊。
多對多多對多的關系可以分解成一對多關系,例如:學生選課,學生與課程之間的關系:
sc = db.Table("sc", db.Column("sno", db.String(10), db.ForeignKey("students.sno")) db.Column("cno",db.String(10), db.ForeignKey("courses.cno")) ) Class Course(db.Model): __tablename__ = "courses" cno = db.Column(db.String(10), primary_key=True) cname = db.Column(db.String(10), index=True) students = db.relationship("Student", secondary=sc, backref=db.backref("course",lazy="dynamic"), lazy="dynamic" )
sc表由db.Table聲明,我們不需要關心這張表,因為這張表將會由SQLAlchemy接管,它唯一的作用是作為students表和courses表關聯(lián)表,所以必須在db.relationship()中指出sencondary關聯(lián)表參數(shù)。lazy是指查詢時的惰性求值的方式,這里有詳細的參數(shù)說明,而db.backref是聲明反向身份代理,其中的lazy參數(shù)是指明反向查詢的惰性求值方式,SQLAlchemy鼓勵這種方式聲明多對多的關系。
但是如果關聯(lián)表中有自定義的字段,如sc表中添加成績字段則需要更改表聲明方式,將sc更改為繼承db.Model的對象并設置sc:courses = 1:n 和sc:student = 1:n的關系。
Flask-SQLAlchemy查詢中有詳細的說明。創(chuàng)建關系后該如何查詢到對象?
SQLAlchemy有查詢過濾器如下:
過濾器 | 說明 |
---|---|
filter() | 把過濾器添加到原查詢,返回新查詢 |
filter_by() | 把等值過濾器添加到原查詢,返回新查詢 |
limit() | 使用指定值限制原查詢返回的結(jié)果數(shù)量,返回新查詢 |
offset() | 偏移原查詢返回的結(jié)果,返回新查詢 |
order_by() | 排序返回結(jié)果,返回新查詢 |
groupby() | 原查詢分組,返回新查詢 |
這些過濾器返回的結(jié)果都是一個新查詢,我的理解是這些查詢其實是生成的SQL語句,lazy的惰性求值方式也體現(xiàn)在查詢上,而這些語句不能生成需要查詢的對象,需要調(diào)用其他的方法生成對象。
SQL查詢執(zhí)行函數(shù):
方法 | 說明 |
---|---|
all() | 以列表形式返回結(jié)果 |
first() | 返回第一個結(jié)果,如果沒有返回None |
first_or_404() | 返回第一個結(jié)果,如果沒有拋出404異常 |
get() | 返回主鍵對應記錄,沒有則返回None |
get_or_404() | 返回主鍵對應記錄,如果沒有拋出404異常 |
count() | 返回查詢結(jié)果數(shù)量 |
paginate() | 返回paginate對象,此對象用于分頁 |
個人博客
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/37806.html
摘要:最近在開發(fā)的時候遇到這樣一個問題我就好奇了這樣還報不在中的錯沒有顯示調(diào)用啊加一行測試無奈,一個一個翻到之間調(diào)用的每一個函數(shù),終于在找到可疑點但是這里也沒有顯式提交。為什么接下來總結(jié)下大神們的探討。 最近在開發(fā)mdwiki的時候遇到這樣一個問題.Post is unbond to session.我就好奇了 post=Post.query.filter_by(location=locat...
摘要:程序中最常用的莫過于關系型數(shù)據(jù)庫了,也稱數(shù)據(jù)庫。對象是類的實例,表示程序使用的數(shù)據(jù)庫。本文由發(fā)表于個人博客,采用自由轉(zhuǎn)載保持署名非商用禁止演繹協(xié)議發(fā)布。非商業(yè)轉(zhuǎn)載請注明作者及出處。本文標題為插件系列本文鏈接為更多閱讀 簡介 Web 開發(fā)中,一個重要的組成部分便是數(shù)據(jù)庫了。Web 程序中最常用的莫過于關系型數(shù)據(jù)庫了,也稱 SQL 數(shù)據(jù)庫。另外,文檔數(shù)據(jù)庫(如 mongodb)、鍵值對數(shù)據(jù)...
摘要:從零開始用搭建一個網(wǎng)站一介紹了如何搭建環(huán)境,以及應用基本項目結(jié)構。我們要搭建的網(wǎng)站是管理第三方集成的控制臺,類似于。我們先定義一個用戶模型然后在文件夾下創(chuàng)建一個文件。 從零開始用 Flask 搭建一個網(wǎng)站(一) 介紹了如何搭建 Python 環(huán)境,以及 Flask 應用基本項目結(jié)構。我們要搭建的網(wǎng)站是管理第三方集成的控制臺,類似于 Slack。 本篇主要講解數(shù)據(jù)如何在 Flask 應用...
摘要:數(shù)據(jù)庫關系數(shù)據(jù)庫將數(shù)據(jù)保存在表中來模擬應用程序中不同的實體。這些行之間的連接稱作關系,也是關系數(shù)據(jù)庫模型的基礎。就像這個示例中看到的那樣,關系數(shù)據(jù)庫存儲數(shù)據(jù)高效且避免重復。最好的例子就是,支持一組關系數(shù)據(jù)庫引擎,包括流行的和。 數(shù)據(jù)庫就是有組織的存儲應用程序數(shù)據(jù),然后查詢檢索指定需要的那部分。大部分web應用程序都采用基于關系模型的數(shù)據(jù)庫,也稱作結(jié)構化查詢語言(SQL)數(shù)據(jù)庫。但是最近...
閱讀 2919·2021-10-27 14:19
閱讀 549·2021-10-18 13:29
閱讀 1144·2021-07-29 13:56
閱讀 3563·2019-08-30 13:19
閱讀 1940·2019-08-29 12:50
閱讀 1070·2019-08-23 18:16
閱讀 3533·2019-08-22 15:37
閱讀 1909·2019-08-22 15:37