1. 程式人生 > >【Flask】什麼是Flask-SQLAlchemy?

【Flask】什麼是Flask-SQLAlchemy?

目錄

ORM:

SQLAlchemy:

Flask-SQLAlchemy:

安裝及配置:

Flask-SQLAlchemy對資料庫的操作:


在認識Flask-SQLAlchemy之前,先要了解ORM和SQLAlchemy。

ORM:

概念
ORM:物件關係對映,英語:(Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping)
產生背景:
面向物件是從軟體工程基本原則(如耦合、聚合、封裝)的基礎上發展起來的,而關係型資料庫則是從數學理論發展而來的,兩套理論存在顯著的區別。為了解決這個不匹配的現象,物件關係對映技術應運而生。
具體表現:
表現為我們在具體的操作實體物件的時候,就不需要再去和複雜的 SQL 語句打交道,只需簡單的操作實體物件的屬性和方法。ORM 技術是在物件和關係之間提供了一條橋樑,前臺的物件型資料和資料庫中的關係型的資料通過這個橋樑來相互轉化 。
缺點 :
相比較直接使用SQL語句操作資料庫,有效能損失.
根據物件的操作轉換成SQL語句,根據查詢的結果轉化成物件, 在對映過程中有效能損失.

SQLAlchemy:

SQLAlchemy是一個關係型資料庫框架,它提供了高層的 ORM 和底層的原生資料庫的操作,讓開發者不用直接和 SQL 語句打交道,而是通過 Python 物件來操作資料庫,在捨棄一些效能開銷的同時,換來的是開發效率的較大提升。→文件

Flask-SQLAlchemy:

Flask-SQLAlchemy是一個簡化了 SQLAlchemy 操作的flask擴充套件。

安裝及配置:

安裝 flask-sqlalchemy:pip install flask-sqlalchemy
 
資料庫連線配置:
# 配置資料庫的連線(演示使用mysql資料庫)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:

[email protected]/資料庫名'

# 關閉動態追蹤修改的警告資訊 
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 展示sql語句
# app.config['SQLALCHEMY_ECHO'] = True
其它配置:
SQLALCHEMY_POOL_SIZE                資料庫連線池的大小。預設是引擎預設值(通常 是 5 )
SQLALCHEMY_POOL_TIMEOUT        設定連線池的連線超時時間。預設是 10 。
SQLALCHEMY_POOL_RECYCLE         多少秒後自動回收連線。這對MySQL是必要的,它預設移除閒置多於 8 小時的連線。注意如果使用了MySQL Flask-SQLALchemy 自動設定這個值為 2 小時。


常用的Flask_SQLAlchemy關係選項:
backref        在關係的另一模型中新增反向引用
primary join        明確指定兩個模型之間使用的聯結條件
secondary        指定多對多關係中關係表的名字
secondary join        在SQLAlchemy中無法自行決定時,指定多對多關係中的二級聯結條件

 

Flask-SQLAlchemy對資料庫的操作:


# 定義模型兩個模型類,必須繼承自db.Model
class Role(db.Model):
    # 手動指定mysql表的名稱,
    __tablename__ = 'roles'
    id = db.Column(db.Integer,primary_key=True) # 主鍵
    name = db.Column(db.String(32),unique=True)
    # 定義關係引用,第一個引數User表示多方的類名
    # 第二個backref表示的是反向引用,給User模型用,實現多對一的查詢
    # 等號左邊給一方Role使用,backref給多方User使用
    # 通過`lazy='dynamic'`,獲取出來的多的那一部分的資料,就是一個`AppenderQuery`物件了。
    # 這種物件既可以新增新資料,也可以跟`Query`一樣,可以再進行一層過濾。
    # 總而言之一句話:如果你在獲取資料的時候,想要對多的那一邊的資料再進行一層過濾,那麼這時候就         
    # 可以考慮使用`lazy='dynamic'`。
    us = db.relationship('User',backref='role',lazy='dynamic')


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),unique=True)
    pswd = db.Column(db.String(32))
    # 定義外來鍵,指向roles表的主鍵id
    role_id = db.Column(db.Integer,db.ForeignKey('roles.id')) 

增:
向資料庫中新增資料要通過模型類來新增
新增一條資料:db.session.add(模型類類名)
新增多條資料(列表的形式):db.session.add_all([us1,us2,...])
在新增完之後,要有提交和回滾:
db.session.commit()
db.session.rollback()

刪(先找到要刪除的資料):
author = Author.query.get(id)
# 執行刪除
db.session.delete(author)
db.session.commit()
db.session.rollback()

改:
方法一:
user = User.query.first()
user.name = 'dong'
db.session.commit()
方法二:
User.query.filter(User.name=='zhang').update({'name':"li"}) 
db.session.commit() 

資料庫的查詢:

# 定義方法,實現查詢結果顯示成可讀字串
def __repr__(self):
    return 'name:%s' % self.name

get查詢:
User.query.get(1) 引數為主鍵,如果主鍵存在,沒有返回值。

過濾查詢:
User.query.filter(User.name=='wang').first() 都是過濾查詢,接收的引數必須使用模型類的類名,都必須使用查詢執行器。
User.query.filter_by(name='wang').all() 只能使用等值操作,引數為具體模型類的欄位名,使用查詢執行器。
User.query.filter().all() filter查詢不加條件,相當於查詢所有資料。
User.query.filter().limit(2).all() 限制查詢資料的條目數

分頁查詢:
paginate = User.query.filter().paginate(1,2,False) 返回的是paginate物件,第一個引數為當前頁數,第二個引數為每頁的資料,第三個引數為false分頁錯誤不報錯
paginate.page 獲取當前頁數
paginate.pages 獲取總頁數
paginate.items 獲取當前頁數所有資料

排序查詢:
User.query.order_by(User.id.desc()).all() 降序排序
User.query.order_by(User.id.asc()).all() 升序排序
※ limit:限制資料條目數,count:計數
關聯查詢示例:
程式碼中的關係引用定義:
us = db.relationship('User',backref='role')
一對多查詢:使用relationship返回的物件。
>>> r = Role.query.get(1)
# 查詢管理員有多少人
>>> r.us
[name:wang, name:zhou]

多對一查詢:使用反向引用;
>>> User.query.get(2)
name:zhang
>>> u = User.query.get(2)
# 查詢zhang的角色是什麼
>>> u.role
name:user