Flask——資料庫簡介
阿新 • • 發佈:2018-11-30
ORM
ORM:全拼 Object-Relation Mapping 中文名:物件關係對映 主要實現模型物件到關係資料庫資料的對映,比如把資料庫表每條記錄對映為一個模型物件。但是資料庫需要手動建立。 優點 : 只需要面向物件程式設計, 不需要面向資料庫編寫程式碼. 對資料庫的操作都轉化成對類屬性和方法的操作. 不用編寫各種資料庫的sql語句. 實現了資料模型與資料庫的解耦, 遮蔽了不同資料庫操作上的差異. 不在關注用的是mysql、oracle...等. 通過簡單的配置就可以輕鬆更換資料庫, 而不需要修改程式碼. 缺點 : 相比較直接使用SQL語句操作資料庫,有效能損失. 根據物件的操作轉換成SQL語句,根據查詢的結果轉化成物件, 在對映過程中有效能損失. SQLAlchemy:關係型資料庫抽象框架,用來實現ORM 使用Flask-SQLAlchemy擴充套件包來具體實現SQLAlchemy。
Flask_SQLAlchemy的配置說明:
SQLALCEHMY_DATABASE_URI:用於連線資料庫URI SQLALCHEMY_BINDS:一個對映binds到URI的字典 SQLALCHEMY_ECHO:如果設定為True,SQLAlchemy會列印mysql語句 SQLALCHEMY_RECORD_QUERIES:可以顯式的禁用或啟用查詢語句,查詢語句在調式或者測試模式自動啟用。 SQLALCEHMY_NATIVE_UNICODE:可以用於顯式禁用原生unicode支援,當使用不合適的指定無編碼的資料庫預設值時,這對於一些資料庫介面卡是必須的 SQLALCEHMY_POOL_SIZE:資料庫連線池的大小,預設是引擎的預設值,通常是5 SQLALCHEMY_POOL_TIMEOUT:設定連線池的連線超時時間,預設是10 SQLALCHEMY_POOL_RECYCLE:多少秒後自動收回連線,這對Mysql是必要的,它預設移除連線超過8小時的連線。注意如果使用了Mysql。Flask_SQLAlchemy自動設定這個值為2小時。
常用的SQLAlcehmy的欄位型別
Integer :普通整數,一般是32位
SmallInteger: 取值範圍小的整數,一般是16位
BigInteger : 不限制精度的整數
Float : 浮點數
Numeric : 普通整數,一般是32位
String :變長字串
Text : 變長字串,對較長或不限長度的字串做了優化
Unicode :變長Unicode字串
UnicodeText : 變長Unicode字串,對較長或不限長度的字串做了優化
Boolean : 布林值
Date : 時間
Time :日期和時間
LargeBinary : 二進位制檔案
常用的SQLAlcehmy列選項:
primary_key: 如果為True,代表表的主鍵
unique: 如果為True,代表這列不允許出現重複的值
index:如果為True,為這列建立索引,提高查詢效率
nullable:如果為True,允許有空值,如果為False,不允許有空值
default :為這列定義預設值
常用的SQLAlcehmy的關係選項:
backref :在關係的另一模型中新增反向引用
primary join: 明確指定兩個模型之間使用的聯結條件
uselist: 如果為False,不使用列表,而使用標量值
order_by: 指定關係中記錄的排序方式
secondary: 指定多對多關係中關係表的名字
secondary join :在SQLAlchemy中無法自行決定時,指定多對多關係中的二級聯結條件
程式碼
from flask import Flask
# 匯入擴充套件包
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 資料庫指定連線
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:[email protected]/homework'
#動態追蹤修改,無論設定與否,不會影響程式碼的執行。只會提示警告資訊。如果設定為True,會跟蹤資料庫的變化,會影響程式碼的效率,設定為False,不影響程式碼的效率。
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
#展示sql語句:會轉換出mysql建立表操作的原理。
app.config['SQLALCHEMY_ECHO'] = True
# 使用sqlalchemy,需要例項化sqlalchemy,必需傳入例項app,讓策劃嗯需例項app和sqlalchemy進行關聯
db = SQLAlchemy(app)
"""
需求:實現一對多模型類的定義和基本資料的增刪改查
Role(角色)一方,管理員和普通使用者
user(使用者)多方,具體的使用者
實現流程:
1.使用flask_sqlalchemy擴充套件包,配置資料庫的連線
2.定義模型類
"""
# 定義模型類,必須繼承自db.Model
class Role(db.Model):
# 資料庫表名,可以不定義,會預設建立同類型的表名,即role。
# 表名的常見定義樣式:tb_roles;info_roles;
__tablename__ = 'roles'
#定義欄位
id = db.Column(db.Integer,primary_key=True)
info = db.Column(db.String(32),unique=True)
# 一方定義關係:第一個引數表示另外一方的類名,第二個引數backref表示的是反向引用
# role可以讓User物件使用,可以實現多對一的查詢,例如:一個人是管理員還是普通使用者?多對一查詢
# us可以讓Role物件使用,實現一對多的查詢,例如:管理員有多少人?一對多查詢
#關係引用在資料庫中沒有實體
us = db.relationship('User',backref ='role')
#定義__repr__方法:作用是返回一個物件的可讀字串
def __repr__(self):
return 'info:%s' % self.info
#定義使用者模型類:注意外來鍵(角色具體屬於的身份資訊)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
email = db.Column(db.String(32))
pswd = db.Column(db.String(32))
# 多方定義外來鍵,指向一方表名的主鍵id
role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
#定義__repr__方法:
def __repr__(self):
return 'name:%s' % self.name
@app.route('/')
def index():
return 'hello world'
# db.session.rollback() 回滾
"""
Role.query.get(2) get查詢接收的引數為主鍵,如果不存在,返回空
>>> User.query.filter() 返回的基礎的查詢物件
<flask_sqlalchemy.BaseQuery object at 0x10958fb00>
filter和filter_by查詢:都是查詢過濾器,要使用查詢執行器;
User.query.filter(User.name=='wang').all() 引數:必須使用類名.欄位,可以使用運算子>= == <= !=
使用filter居多,因為可以有更多的過濾。
補充:在使用或過濾的時候,需要from sqlalcehmy import or_ 先導,不能直接使用。
User.query.filter_by(name='wang').all()引數:只需要使用欄位名,不能使用運算子。
查詢排序:
>>> User.query.filter().order_by(User.id.desc()).all() desc()表示降序排序
[name:zhou, name:chen, name:zhang, name:wang]
>>> User.query.filter().order_by(User.id.asc()).all() asc()表示升序排序
[name:wang, name:zhang, name:chen, name:zhou]
分頁:第一個引數表示頁數,第二個引數表示每頁條目數,第三個引數分頁異常不報錯
>>> pa = User.query.filter().paginate(1,2,False)
>>> pa.items # 獲取分頁後的資料
[name:wang, name:zhang]
>>> pa.pages # 獲取分頁後的總頁數
2
>>> pa.page # 獲取當前頁數
1
>>> pa = User.query.filter().paginate(2,2,False)
>>> pa.items
[name:chen, name:zhou]
>>> pa.pages
2
>>> pa.page
2
"""
if __name__ == '__main__':
# 刪除表
db.drop_all()
# 建立表
db.create_all()
#新增測試資料
ro1 = Role(info='admin')
ro2 = Role(info='user')
# session表示資料庫會話物件,add_all表示新增多條資料/add()
# commit表示提交資料到資料庫
db.session.add_all([ro1, ro2])
db.session.commit()
us1 = User(name='wang', email='[email protected]', pswd='123456', role_id=ro1.id)
us2 = User(name='zhang', email='[email protected]', pswd='201512', role_id=ro2.id)
us3 = User(name='chen', email='[email protected]', pswd='987654', role_id=ro2.id)
us4 = User(name='zhou', email='[email protected]', pswd='456789', role_id=ro1.id)
db.session.add_all([us1, us2, us3, us4])
db.session.commit()
app.run(debug=True)
常用SQLAlchemy查詢資料庫:
filter(): 把過濾器新增到原查詢上,返回一個新查詢
filter_by(): 把等值過濾器新增到原查詢上,返回一個新查詢 limit 使用指定的值限定原查詢返回的結果
offset(): 偏移原查詢返回的結果,返回一個新查詢
order_by(): 根據指定條件對原查詢結果進行排序,返回一個新查詢
group_by(): 根據指定條件對原查詢結果進行分組,返回一個新查詢
常用SQLAlchemy查詢資料庫:
all() 以列表形式返回查詢的所有結果
first() 返回查詢的第一個結果,如果未查到,返回None
first_or_404() 返回查詢的第一個結果,如果未查到,返回404
get() 返回指定主鍵對應的行,如不存在,返回None
get_or_404() 返回指定主鍵對應的行,如不存在,返回404
count() 返回查詢結果的數量
paginate() 返回一個Paginate物件,它包含指定範圍內的結果
資料庫的查詢操作:
first()返回查詢到的第一個物件
all()返回查詢到的所有物件
filter_by()精準查詢
filter()模糊查詢
get()引數為主鍵,如果主鍵不存在沒有返回內容
not_相當於取反,但是and_,or_xu需要匯入
查詢資料後刪除:需要先給查詢後一個變數儲存,然後db.session.delete(變數名),注意需要提交。
更新資料:和刪除資料類似,然後修改提交。
關聯查詢:
查詢角色的所有使用者
**#查詢roles表id為1的角色
ro1 = Role.query.get(1)
#查詢該角色的所有使用者
ro1.us.all()**
**查詢使用者所屬角色
#查詢users表id為3的使用者
us1 = User.query.get(3)
#查詢使用者屬於什麼角色
us1.role**