目錄html
Flask-SQLAlchemy使用起來很是有趣,對於基本應用程序來講很是簡單,而且適用於大型應用程序。python
安裝mysql
pip install flask-sqlalchemy
Flask-SQLAlchemy存在如下的配置值,Flask-SQLAlchemy從主Flask配置中加載這些值,能夠經過各類方式進行填充。請注意,在建立引擎後其中一些內容沒法修改,所以須要確保儘早的進配置,而且不要在運行時對其進行修改。sql
配置名稱 | 介紹 |
---|---|
SQLALCHEMY_DATABASE_URI | 將要被用於數據庫連接的URI。 例如: mysql://username:password@server/db mysql+pymysql://root:123456@localhost:3306/TTC |
SQLALCHEMY_BINDS | 一個將會綁定多種數據庫的字典。 更多詳細信息請看官文 綁定多種數據庫. |
SQLALCHEMY_ECHO | 若是設置爲True,SQLAlchemy會將記錄全部標準錯誤聲明,這對調試很是有用。 |
SQLALCHEMY_RECORD_QUERIES | 能夠用於禁用或啓用查詢記錄的顯示 。 查詢記錄會自動的在調試或測試模式下進行 。 |
SQLALCHEMY_NATIVE_UNICODE | 能夠用來啓用或禁用本地對 unicode 的支持。 |
SQLALCHEMY_POOL_SIZE | 數據庫池的大小。 默認與數據庫引擎的值相同 (一般爲 5) |
SQLALCHEMY_POOL_TIMEOUT | 指定池的鏈接超時(以秒爲單位)。 |
SQLALCHEMY_POOL_RECYCLE | 自動循環鏈接的秒數。這是MySQL所必須的,默認狀況下,閒置8小時後會刪除鏈接。若是使用MySQL,SQLAlchemy會自動將其設置爲2小時,一些後端可能使用不一樣的默認超時值。 |
SQLALCHEMY_MAX_OVERFLOW | 控制鏈接池達到最大大小後還能夠建立的鏈接數,當這些附加鏈接返回到鏈接池時,它們將會被斷開並丟棄。 |
SQLALCHEMY_TRACK_MODIFICATIONS | 若是設置爲True,Flask-SQLAlchemy將跟蹤對對象的修改,併發出信號。默認值爲None,他能夠啓用跟蹤功能,但會發出警告,代表它在未來會被默認禁用。這須要額外的內存,若是不須要,應該禁用。 |
下面對SQLAlchemy進行配置數據庫
app.pyflask
from flask import Flask from flask_script import Manager from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # 建立一個Flask app對象 # 數據庫連接的配置,此項必須,格式爲(數據庫+驅動://用戶名:密碼@數據庫主機地址:端口/數據庫名稱) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost:3306/flask_ttc' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 跟蹤對象的修改,在本例中用不到調高運行效率,因此設置爲False db = SQLAlchemy(app=app) # 爲哪一個Flask app對象建立SQLAlchemy對象,賦值爲db manager = Manager(app=app) # 初始化manager模塊 @app.route('/') def hello_world(): reutrn 'Hello World!' if __name__ == '__main__': manager.run() # 運行服務器
這裏的模型就的咱們口中一般說的MTV中Model,顯然app.py 中用@app.route()裝飾器裝飾的就是View了,Templates中存在的html模板文件就的咱們的T了。後端
這裏簡單的寫一個Modelruby
models.pybash
from app import db # 導入app文件中的SQLAlchemy對象 class Student(db.Model): # 繼承SQLAlchemy.Model對象,一個對象表明了一張表 s_id= db.Column(db.Integer, primary_key=True, autoincrement=True, unique=True) # id 整型,主鍵,自增,惟一 s_name = db.Column(db.String(20)) # 名字 字符串長度爲20 s_age = db.Column(db.Integer, default=20) # 年齡 整型,默認爲20 __tablename__ = 'student' # 該參數可選,不設置會默認的設置表名,若是設置會覆蓋默認的表名 def __init__(self, name, age): # 初始化方法,能夠對對象進行建立 self.s_name = name self.s_age = age def __repr__(self): # 輸出方法,與__str__相似,可是可以重現它所表明的對象 return '<Student %r, %r, %r>' % (self.s_id, self.s_name, self.sage)
列的類型是Column的第一個參數。能夠直接指定他們,也能夠的調用他們以進一步的指定他們的長度。如下類型是最多見的:服務器
類型 | 介紹 |
---|---|
Integer | 一個整數 |
String(size) | 一個字符串,並能夠設置它的最大長度 |
Text | 更長的unicode文本 |
DateTime | 經過Python的datetime對象來表示時間日期 |
Float | 存儲一個浮點數 |
Boolean | 存儲一個布爾值 |
PickleType | 存儲一個序列化( Pickle )後的Python對象 |
LargeBinary | 存儲巨大長度的二進制數據 |
咱們能夠經過交互式的環境來建立數據庫中的表
>>> from app import db # 引入SQLAlchemy >>> from models import * # 映入加載了model的SQLAlchemy對象,db >>> db.create_all() # 建立表
這樣數據庫中就已經存在student表了
這些操做均可以經過SQL語句來實現
sql = 'select * from student;' stus = db.session.execute(sql)
# 插入一條 stu = Student('TTC', 22) db.session.add(stu) db.session.commit() # 若是添加的對象是列表,使用db.session.add_all(list) stus = [] db.session.add_all(stus) db.session.commit()
stu = Student.query.get(1) # 須要刪除的對象 db.session.delete(stu) # 刪除 db.session.commit() # 提交事務
stu = Student.query.get(1) # 須要修改的對象 stu.s_age = 18 # 修改值 db.session.commit() # 提交
stu = Student.query.filter(s_name='TTC').first() # 若是查詢一個不存在的會返回一個None
stu = Student.query.get(1) # 主鍵查詢
# __lt__ 小於 __le__小於等於 __gt__ 大於 __ge__ 大於等於 Student.query.filter(Student.s_age.__lt__(16)) # 小於16歲 Student.query.filter(Student.s_age.__le__(16)) # 小於等於16歲 Student.query.filter(Student.s_age.__gt__(16)) # 大於16歲 Student.query.filter(Student.s_age.__ge__(16)) # 大於等於16歲
# 使用in_方法獲取與列表中值相匹配的值 Student.query.filter(Student.s_age.in_([16, 17, 18, 19, 20]))
Student.query.order_by('s_age') # 按年齡排序,默認升序,在前面加-號爲降序'-s_age'
Student.query.filter(s_age=18).offset(2).limit(3) # 跳過二條開始查詢,限制輸出3條
Student.query.filter(Student.s_age == 18, Student.s_name == 'TTC') # 也能夠經過and_而且 or_或者 not_非 的方法來進行查詢 Student.query.filter(and_(Student.s_age == 18, Student.s_name == 'TTC')) Student.query.filter(or_(Student.s_age == 18, Student.s_name == 'TTC')) Student.query.filter(not_(Student.s_age == 18, Student.s_name == 'TTC'))
最多見的關係就是一對多的關係。由於關係在它們創建以前就已經聲明,可使用字符串來指代尚未建立的類。
好比班級和學生的關係即爲一對多的關係,一個班級對應多名學生。
models.py
from app import db class Grade(db.Model): """班級表""" g_id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 班級id g_name = db.Column(db.String(20)) # 班級名稱 g_desc = db.Column(db.String(100)) # 描述 students = db.relationship('Student', backref='grade', lazy=True) # 關係 __tablename__ = 'grade' # 表名 def __init__(self, name, desc): # 初始化方法 self.g_name = name # 名稱 self.g_desc = desc # 描述 def __repr__(self): # 輸出方法,顯示對象內容 return '<Grade %r, %r, %r>' % (self.g_id, self.g_name, self.g_desc) class Student(db.Model): """學生表""" s_id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 學生ID s_name = db.Column(db.String(20)) # 學生姓名 s_age = db.Column(db.Integer, default=20) # 學生年齡 g_id = db.Column(db.Integer, db.ForeignKey('grade.g_id')) # 外鍵 __tablename__ = 'student' # 表名 def __init__(self, name, age, g_id): # 初始化方法 self.s_name = name # 姓名 self.s_age = age # 年齡 self.g_id = g_id # 班級ID def __repr__(self): # 輸出方法,顯示對象內容 return '<Student %r, %r, %r>' % (self.s_id, self.s_name, self.s_age)
經過學生獲取班級
g_id = Student.query.get(12).grade.g_id
經過班級獲取學生
stus = Grade.query.get(2).students
須要使用一對一的關係,和一對多的關係的寫法是同樣的,只是在relationship中有一個參數不一樣,須要將uselist=Flase
,這樣兩個表之間的關係就變成了一對一的關係。其參數的含義就是不使用列表,兩個表之間只有一條對應一條的關聯。
若是想使用多對多關係,須要定義一一個用於關係的輔助表,對於這個輔助表,建議不使用模型,而是採用一個實際的表:
咱們接着以前的寫,加入學生(Student)和課程(Course)的關係
from app import db # 引入模塊 class Student(db.Model): """學生表""" s_id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 學生ID s_name = db.Column(db.String(20)) # 學生姓名 s_age = db.Column(db.Integer, default=20) # 學生年齡 g_id = db.Column(db.Integer, db.ForeignKey('grade.g_id')) # 班級ID __tablename__ = 'student' # 學生表 def __init__(self, name, age, g_id): # 初始化方法 self.s_name = name # 名稱 self.s_age = age # 年齡 self.g_id = g_id # 班級ID def __repr__(self): # 格式化輸出顯示對象中的值 return '<Student %r, %r, %r>' % (self.s_id, self.s_name, self.s_age) # 輔助表 記錄學生表和課程表的多對多關係 sc = db.Table('sc', # 表名 db.Column('s_id', db.Integer, db.ForeignKey('student.s_id'), primary_key=True), db.Column('c_id', db.Integer, db.ForeignKey('course.c_id'), primary_key=True) ) class Course(db.Model): """課程表""" c_id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 課程的ID c_name = db.Column(db.String(20)) # 課程名稱 students = db.relationship('Student', secondary=sc, backref='courses') # 與學生表的關係 # secondary指定副表名稱 def __init__(self, name): # 初始化方法 self.c_name = name # 課程名 def __repr__(self): # 格式化輸出顯示對象中的值 return '<Course %r, %r >' % (self.c_id, self.c_name)
多對多關係的數據插入方式
stu = Student.query.get(s_id) # 獲取學生對象 cou = Course.query.get(c_id) # 獲取課程對象 # 方式一 cou.students.append(stu) # 創建學生和課程的關係 db.session.add(cou) # 爲會話添加事務 # 方式二 stu.courses.append(cou) db.session.add(stu) # 方式一和方式二等效 db.session.commit() # 提交事務
多對多關係的數據刪除方式
stu = Student.query.get(s_id) cou = Course.query.get(c_id) # 方式一 cou.students.remove(stu) # 方式二 stu.students.remove(cou) # 方式一和方式二等效 db.session.commit()
多對多關係互相查詢
經過學生查課程
cous = Student.query.get(s_id).courses
經過課程查學生
stus = Course.query.get(c_id).students