FlaskSQLAlchemy框架使用學習筆記

FlaskSQLAlchemy框架使用學習筆記

  • SQLAlchemy是一個關係型數據庫框架,它提供了高層的 ORM 和底層的原生數據庫的操作。flask-sqlalchemy 是一個簡化了 SQLAlchemy 操作的flask擴展。
  • SQLALchemy 實際上是對數據庫的抽象,讓開發者不用直接和 SQL 語句打交道,而是通過 Python 對象來操作數據庫,在捨棄一些性能開銷的同時,換來的是開發效率的較大提升

安裝

  • 安裝 flask-sqlalchemy
pip install flask-sqlalchemy
  • 如果連接的是 mysql 數據庫,需要安裝 mysqldb
pip install flask-mysqldb

創建完flask項目後,從flask_sqlalchemy中導入SQLAlchemy並實例化,代碼如下

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)

數據庫連接設置

  • 在 Flask-SQLAlchemy 中,數據庫使用URL指定,而且程序使用的數據庫必須保存到Flask配置對象的 SQLALCHEMY_DATABASE_URI 鍵中
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:[email protected]:3306/monkey'
  • 其他設置:
# 是否追蹤修改,一般設置爲False,因爲浪費資源,並且後期版本中將取消此設置
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 查詢時會打印顯示原始SQL語句
app.config['SQLALCHEMY_ECHO'] = True
  • 配置完成需要去 MySQL 中創建項目所使用的數據庫
$ mysql -uroot -p
$ 輸入密碼
$ create database moneky charset utf8;

數據庫連接和sqlalchemy連接數據庫代碼一樣,定義好數據庫連接後,我們就可以定義模型了(注意:模型繼承的類是db.Model,直接從db導入即可),代碼如下:

class User(db.Model):
    __tablename__ = "user"
    id = db.db.Column(db.Integer , primary_key=True , autoincrement=True)
    name = db.db.Column(db.String(50) , nullable=False)

常用的SQLAlchemy字段類型

類型名 python中類型 說明
Integer int 普通整數,一般是32位
SmallInteger int 取值範圍小的整數,一般是16位
BigInteger int或long 不限制精度的整數
Float float 浮點數
Numeric decimal.Decimal 普通整數,一般是32位
String str 變長字符串
Text str 變長字符串,對較長或不限長度的字符串做了優化
Unicode unicode 變長Unicode字符串
UnicodeText unicode 變長Unicode字符串,對較長或不限長度的字符串做了優化
Boolean bool 布爾值
Date datetime.date 時間
Time datetime.datetime 日期和時間
LargeBinary str 二進制文件

常用的SQLAlchemy列選項

選項名 說明
primary_key 如果爲True,代表表的主鍵
unique 如果爲True,代表這列不允許出現重複的值
index 如果爲True,爲這列創建索引,提高查詢效率
nullable 如果爲True,允許有空值,如果爲False,不允許有空值
default 爲這列定義默認值

常用的SQLAlchemy參數

選項名 說明
backref 在關係的另一模型中添加反向引用
secondary 指定多對多關係中關係表的名字
primaryjoin 用在一對多或者多對一的關係中,默認情況連接條件就是主鍵與另一端的外鍵
order_by order_by="desc(Address.email)"地址按照email排序

SQLAlchemy中的映射關係

有四種,分別是一對多,多對一,一對一,多對多

一對多(one to many):

因爲外鍵(ForeignKey)始終定義在多的一方.如果relationship定義在多的一方,那就是多對一,一對多與多對一的區別在於其關聯(relationship)的屬性在多的一方還是一的一方,如果relationship定義在一的一方那就是一對多.
這裏的例子中,一指的是Parent,一個parent有多個child:

class Parent(db.Model):
    __tablename__ = 'parent'
    id = db.Column(Integer,primary_key = True)
    children = relationship("Child",backref='parent')
 
class Child(db.Model):
    __tablename__ = 'child'
    id = db.Column(Integer,primary_key = True)
    parent_id = db.Column(Integer,ForeignKey('parent.id'))

多對一(many to one):

這個例子中many是指parent了,意思是一個child可能有多個parent(父親和母親),這裏的外鍵(child_id)和relationship(child)都定義在多(parent)的一方:

class Parent(db.Model):
    __tablename__ = 'parent'
    id = db.Column(Integer, primary_key=True)
    child_id = db.Column(Integer, ForeignKey('child.id'))
    child = relationship("Child", backref="parents")
 
class Child(db.Model):
    __tablename__ = 'child'
    id = db.Column(Integer, primary_key=True)

爲了建立雙向關係,可以在relationship()中設置backref,Child對象就有parents屬性.設置 cascade= ‘all’,可以級聯刪除:

class Parent(db.Model):
    __tablename__ = 'parent'
    id = db.Column(Integer,primary_key = True)
    children = relationship("Child",cascade='all',backref='parent')
 
def delete_parent():
    session = Session()
    parent = session.query(Parent).get(2)
    session.delete(parent)
    session.commit()

不過不設置cascade,刪除parent時,其關聯的chilren不會刪除,只會把chilren關聯的parent.id置爲空,設置cascade後就可以級聯刪除children

一對一(one to one):

一對一就是多對一和一對多的一個特例,只需在relationship加上一個參數uselist=False替換多的一端就是一對一:
從一對多轉換到一對一:

class Parent(db.Model):
    __tablename__ = 'parent'
    id = db.Column(Integer,primary_key = True)
    children = relationship("Child",cascade='all',backref='parent')
 
def delete_parent():
    session = Session()
    parent = session.query(Parent).get(2)
    session.delete(parent)
    session.commit()

從多對一轉換到一對一:

class Parent(db.Model):
    __tablename__ = 'parent'
    id = db.Column(Integer, primary_key=True)
    child_id = db.Column(Integer, ForeignKey('child.id'))
    child = relationship("Child", backref=backref("parent", uselist=False))
 
class Child(db.Model):
    __tablename__ = 'child'
    id = db.Column(Integer, primary_key=True)

多對多(many to many):

多對多關係需要一箇中間關聯表,通過參數secondary來指定,

from sqlalchemy import Table,Text
post_keywords = Table('post_keywords',Base.metadata,
        db.Column('post_id',Integer,ForeignKey('posts.id')),
        db.Column('keyword_id',Integer,ForeignKey('keywords.id'))
)
 
class BlogPost(db.Model):
    __tablename__ = 'posts'
    id = db.Column(Integer,primary_key=True)
    body = db.Column(Text)
    keywords = relationship('Keyword',secondary=post_keywords,backref='posts')
 
class Keyword(db.Model):
    __tablename__ = 'keywords'
    id = db.Column(Integer,primary_key = True)
    keyword = db.Column(String(50),nullable=False,unique=True)

定義模型類 & 增刪改

創建表

db.create_all()

刪除表

db.drop_all()

插入一條數據

user = User(name='monkey')
db.session.add(user)
db.session.commit()

數據查詢

常用的SQLAlchemy查詢過濾器

過濾器 說明
filter() 把過濾器添加到原查詢上,返回一個新查詢
filter_by() 把等值過濾器添加到原查詢上,返回一個新查詢
limit 使用指定的值限定原查詢返回的結果
order_by() 根據指定條件對原查詢結果進行排序,返回一個新查詢

常用的SQLAlchemy查詢執行器

方法 說明
all() 以列表形式返回查詢的所有結果
first() 返回查詢的第一個結果,如果未查到,返回None
first_or_404() 返回查詢的第一個結果,如果未查到,返回404
get() 返回指定主鍵對應的行,如不存在,返回None
get_or_404() 返回指定主鍵對應的行,如不存在,返回404
count() 返回查詢結果的數量
paginate() 返回一個Paginate對象,它包含指定範圍內的結果
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章