1. 程式人生 > >三十四、python學之Flask框架(六)資料庫:mysql資料庫及Flask-SQLAlchemy

三十四、python學之Flask框架(六)資料庫:mysql資料庫及Flask-SQLAlchemy

一、資料庫知識回顧:

1.SQL:關係型資料庫,支援結構化查詢語言:

  • 關係型資料庫:以表的形式儲存;
  • 支援結構化查詢語言:SQL語句;
  • 列數固定;行數可變,定義資料,主鍵、外來鍵,引用同表或不同表的主鍵,這種聯絡稱為關係.

2.關於正規化:

第一正規化:原子性;表單中的每一列都是不可分割的
第二正規化:在滿足第一正規化的基礎上,消除非主屬性對主屬性的依賴;
第三正規化:在滿足第二正規化的基礎上,消除非主屬性之間的依賴;

3. 補充:

冗餘欄位的作用:以空間換時間;

二、ORM:

1.什麼是ORM:

  • ORM (Object-Relation Mapping.): 物件-關係對映.
  • 主要實現模型物件到關係資料庫資料的對映.

比如:把資料庫表中每條記錄對映為一個模型物件
在這裡插入圖片描述

ORM圖解:

ORM圖解:

2.ORM的優點:

只需要面向物件程式設計, 不需要面向資料庫編寫程式碼.

對資料庫的操作都轉化成對類屬性和方法的操作.
不用編寫各種資料庫的sql語句.

實現了資料模型與資料庫的解耦, 遮蔽了不同資料庫操作上的差異.

不在關注用的是mysql、oracle…等.
通過簡單的配置就可以輕鬆更換資料庫, 而不需要修改程式碼.

3.ORM的缺點:

相比較直接使用SQL語句操作資料庫,有效能損失.
根據物件的操作轉換成SQL語句,根據查詢的結果轉化成物件, 在對映過程中有效能損失.

三、SQLAlchemy:

1.什麼是SQLAlchemy:

(ppt23圖片)

  • SQLAlchemy(翻譯:鍊金術):就是對資料庫的抽象;
  • ORM:物件關係對映;
  • SQLAlchemy:資料庫抽象框架,實現ORM;
  • 使用Flask-SQLAlchemy擴充套件包,是SQLAlchemy的具體實現;

2. Flask-SQLAlchemy安裝及設定:

2.1 SQLAlchemy概述:

  • SQLALchemy 實際上是對資料庫的抽象,讓開發者不用直接和 SQL 語句打交道,而是通過 Python 物件來操作資料庫,在捨棄一些效能開銷的同時,換來的是開發效率的較大提升
  • SQLAlchemy是一個關係型資料庫框架,它提供了高層的 ORM 和底層的原生資料庫的操作。flask-sqlalchemy 是一個簡化了 SQLAlchemy 操作的flask擴充套件。
  • 文件地址:http://docs.jinkan.org/docs/flask-sqlalchemy

2.2 安裝:

安裝 flask-sqlalchemy

pip install flask-sqlalchemy

如果連線的是 mysql 資料庫,需要安裝 mysqldb

pip install flask-mysqldb

3.學習Flask_SQLAlchemy:

3.1. 使用Flask_SQLAlchemy連線資料庫:

app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘資料庫型別://使用者名稱:密碼@ip和port/資料庫名稱’
app表示Flask程式例項
config是Flask配置物件
SQLALCHEMY_DATABASE_URI表示連結資料庫的地址,為固定名稱。
例如:
‘mysql://user:[email protected]/database’

3.2 其他設定:

# 動態追蹤修改設定,如未設定只會提示警告
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
#查詢時會顯示原始SQL語句
app.config['SQLALCHEMY_ECHO'] = True

3.3 其他配置:

名字 備註
SQLALCHEMY_DATABASE_URI 用於連線的資料庫 URI 。例如:sqlite:////tmp/test.dbmysql://username:[email protected]/db
SQLALCHEMY_BINDS 一個對映 binds 到連線 URI 的字典。更多 binds 的資訊見用 Binds 操作多個數據庫
SQLALCHEMY_ECHO 如果設定為Ture, SQLAlchemy 會記錄所有 發給 stderr 的語句,這對除錯有用。(列印sql語句)
SQLALCHEMY_RECORD_QUERIES 可以用於顯式地禁用或啟用查詢記錄。查詢記錄 在除錯或測試模式自動啟用。更多資訊見get_debug_queries()。
SQLALCHEMY_NATIVE_UNICODE 可以用於顯式禁用原生 unicode 支援。當使用 不合適的指定無編碼的資料庫預設值時,這對於 一些資料庫介面卡是必須的(比如 Ubuntu 上 某些版本的 PostgreSQL )。
SQLALCHEMY_POOL_SIZE 資料庫連線池的大小。預設是引擎預設值(通常 是 5 )
SQLALCHEMY_POOL_TIMEOUT 設定連線池的連線超時時間。預設是 10
SQLALCHEMY_POOL_RECYCLE 多少秒後自動回收連線。這對 MySQL 是必要的, 它預設移除閒置多於 8 小時的連線。注意如果 使用了 MySQL , Flask-SQLALchemy 自動設定 這個值為 2 小時。

4.連線其他資料庫

完整連線 URI 列表請跳轉到 SQLAlchemy 下面的文件 (Supported Databases) 。這裡給出一些 常見的連線字串。

  • Postgres:
postgresql://scott:[email protected]/mydatabase
  • MySQL:
mysql://scott:[email protected]/mydatabase
  • Oracle:
oracle://scott:[email protected]:1521/sidname
  • SQLite (注意開頭的四個斜線):
sqlite:////absolute/path/to/foo.db

5.常用的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 二進位制檔案

6.常用的SQLAlchemy列選項

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

7.常用的SQLAlchemy關係選項:

選項名 說明
backref 在關係的另一模型中新增反向引用
primary join 明確指定兩個模型之間使用的聯結條件
uselist 如果為False,不使用列表,而使用標量值
order_by 指定關係中記錄的排序方式
secondary 指定多對多關係中關係表的名字
secondary join 在SQLAlchemy中無法自行決定時,指定多對多關係中的二級聯結條件

注意:
重新學習一下資料庫的關係(一對一,一對多,多對多);
ER模型;
補充到資料庫相關的文章中

四、資料庫的基本操作:

1.建立模型類:

匯入模板

from flask import Flask
# 使用flask_sqlslchemy擴充套件
from flask_sqlalchemy import SQLAlchemy

例項化物件,並配置資料庫:

app = Flask(__name__)

# 配置連線mysql資料庫
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:[email protected]:3306/python32"
# 關閉動態追蹤修改的警告
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
#展示sql語句
app.config["SQLALCHEMY_ECHO"] = True

# 例項化SQLAlchemy物件
db = SQLAlchemy(app)

建立資料表關係類:

建立角色關係類:

# 需求:實現一對多的關係對映,角色(管理員和普通使用者)和使用者,Role為一方,User為多方
# 定義模型類:必須繼承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給多方使用
    us = db.relationship("User", backref = 'role')

建立使用者關係類:

# 定義使用者表類
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(128),unique=True)
    # 指定外來鍵, 指向roles的id屬性
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

主函式:

if __name__ == '__main__':
    # 刪除資料表
    db.drop_all()
    # 建立資料表
    db.create_all()

    # 例項化模型類物件,新增測試資料
    ro1 = Role(name = "admin")
    ro2 = Role(name = "user")
    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)