Flask-SQLAlchemy 學習總結

初始化和配置

ORM(Object Relational Mapper) 對象關係映射。指將面對對象得方法映射到數據庫中的關係對象中。
Flask-SQLAlchemy是一個Flask擴展,可以支持多種數據庫後臺,咱們能夠不須要關心SQL的處理細節,操做數據庫,一個基本關係對應一個類,而一個實體對應類的實例對象,經過調用方法操做數據庫。Flask-SQLAlchemy有很完善的文檔。python

Flask-SQLAlchemy是經過URL指定數據庫的鏈接信息的。
初始化的兩種方法以下(以鏈接Mysql數據庫爲例):mysql

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)

或者sql

from flask_sqlalchemy import SQLAlchemy
from flask import FLask
db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    db.init_app(app)
    return app

二者的區別在於:第一種不須要啓動flask的app_context;可是第二種方法則須要,由於可能會建立多個Flask應用,可是個人理解是通常地開發時,Flask實例是延遲建立的,由於在運行時難以修改配置信息,這種方法符合這種狀況。
Flask-SQLAlchemy的則須要在Flask.config中聲明。更多詳細信息須要查配置。例如配置信息中指出SQLAlchemy是能夠綁定多個數據庫引擎。再例如:在新浪SAE雲平臺開發我的博客時遇到gone away這種問題就須要添加SQLALCHEMY_POOL_RECYCLE信息,新浪開發者文檔中有說明。數據庫


SQLALchemy處理 對象->關係

SQLAlchemy是如何處理對象到關係的?實例來自於數據庫系統概論內容。flask

簡單實例

建立學生students表segmentfault

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文檔說明建立對象須要繼承db.Model類關聯數據表項,db.Model類繼承Query類提供有數據查詢方法;__tablename__指定數據庫的表名,在Flask-SQLAlchemy中是可省的。Column指定表字段。app

SQLAlchemy支持字段類型有:函數

類型名 python類型 說明
Integer int 普通整數,32位
Float float 浮點數
String str 變長字符串
Text str 變長字符串,對較長字符串作了優化
Boolean bool 布爾值
PickleType 任何python對象 自動使用Pickle序列化

來源於Simple ExampleFlask Web開發有更詳細的內容。
其他的參數指定屬性的配置選項,經常使用的配置選項以下:優化

選項名 說明
primarykey 若是設爲True,表示主鍵
unique 若是設爲True,這列不重複
index 若是設爲True,建立索引,提高查詢效率
nullable 若是設爲True,容許空值
default 爲這列定義默認值

如使用default默認time屬性以下:代理

time = db.Column(db.Date, default=datetime.utcnow)

說明default能夠接受lambda表達式。

一對多

按建立單張表的方法,建立學院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指定,傳入的參數是表的字段。db.relations它聲明的屬性不做爲表字段,第一個參數是關聯類的名字,backref是一個反向身份的代理,至關於在Student類中添加了dept的屬性。例如,有Deptment實例dept和Student實例stu。dept.students.count()將會返回學院學生人數;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表關聯表,因此必須在db.relationship()中指出sencondary關聯表參數。lazy是指查詢時的惰性求值的方式,這裏有詳細的參數說明,而db.backref是聲明反向身份代理,其中的lazy參數是指明反向查詢的惰性求值方式,SQLAlchemy鼓勵這種方式聲明多對多的關係。

可是若是關聯表中有自定義的字段,如sc表中添加成績字段則須要更改表聲明方式,將sc更改成繼承db.Model的對象並設置sc:courses = 1:nsc:student = 1:n的關係。


SQLALchemy處理 關係->對象

Flask-SQLAlchemy查詢中有詳細的說明。建立關係後該如何查詢到對象?

SQLAlchemy有查詢過濾器以下:

過濾器 說明
filter() 把過濾器添加到原查詢,返回新查詢
filter_by() 把等值過濾器添加到原查詢,返回新查詢
limit() 使用指定值限制原查詢返回的結果數量,返回新查詢
offset() 偏移原查詢返回的結果,返回新查詢
order_by() 排序返回結果,返回新查詢
groupby() 原查詢分組,返回新查詢

這些過濾器返回的結果都是一個新查詢,個人理解是這些查詢實際上是生成的SQL語句,lazy的惰性求值方式也體如今查詢上,而這些語句不能生成須要查詢的對象,須要調用其餘的方法生成對象。

SQL查詢執行函數:

方法 說明
all() 以列表形式返回結果
first() 返回第一個結果,若是沒有返回None
first_or_404() 返回第一個結果,若是沒有拋出404異常
get() 返回主鍵對應記錄,沒有則返回None
get_or_404() 返回主鍵對應記錄,若是沒有拋出404異常
count() 返回查詢結果數量
paginate() 返回paginate對象,此對象用於分頁

我的博客

相關文章
相關標籤/搜索