Flask入門數據庫框架flask-SQLAlchemy(十)


​ Web程序開發中最重要的莫過於關系型數據庫,即SQL 數據庫,另外文檔數據庫(如 mongodb)、鍵值對數據庫(如 redis)慢慢變得流行.

原因 : 我們不直接使用這些數據庫引擎提供的 Python 包,而是使用對象關系映射(Object-Relational Mapper, ORM)框架,是因為它將低層的數據庫操作指令抽象成高層的面向對象操作。也就是說,如果我們直接使用數據庫引擎,我們就要寫 SQL 操作語句,但是,如果我們使用了 ORM 框架,我們對諸如表、文檔此類的數據庫實體就可以簡化成對 Python 對象的操作。

(1) Flask - SQLAlchemy

Flask使用的ORM框架為 SQLAlchemy,數據庫采用了URL指定,下面我們列舉幾種數據庫引擎:

數據庫引擎 URL指定
MySQL mysql://username:password@hostname/database
Postgres postgresql://username:password@hostname/database
SQLite (Unix) sqlite:////absolute/path/to/database
SQLite (Windows) sqlite:///c:/absolute/path/to/database

注意:

  1. username 和 password 表示登錄數據庫的用戶名和密碼
  2. hostname 表示 SQL 服務所在的主機,可以是本地主機(localhost)也可以是遠程服務器
  3. database 表示要使用的數據庫 , SQLite 數據庫不需要使用服務器,它使用硬盤上的文件名作為 database

ORM使用的優點:

  1. 增加少sql的重復使用率
  2. 使表更加的可讀性
  3. 可移植性

(2) SQLAlchemy操作sql原生

安裝操作數據庫的模塊

pip3 install pymysql

安裝 flask-sqlalchemy

sudo pip3 install flask-sqlalchemy

配置路徑

DB_URI = 'mysql+pymysql://root:password@host:port/database'

下面先看下sqlalchemy操作的寫法:

from sqlalchemy import create_engine

HOST = '127.0.0.1'
USERNAME = 'root'
PASSWORD = '123456'
DATABASE = 'demo'  #數據庫名
PORT = 3306
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOST,PORT,DATABASE)
#創建引擎
engine = create_engine(DB_URI)

with engine.connect() as db:
    data = db.execute('select * from user') #從user表中獲取全部數據
    db.execute('delete from user where id=1')  #刪除id=1的數據

(3) 設計數據表

1 字段類型

類型名 python中的類型 說明
Integer int 存儲整形 32位
SmallInteger int 小整形 16為
BigInteger int 大整形
Float float 浮點數
String str 字符串 varchar
Text str 長文本
Boolean bool bool值
Date datetimedate 日期
Time datetime.time 時間
datetime datetime.datetime 時間日期

2 可選條件

選項 說明
primary_key 主鍵, 如果設為True,表示主鍵
unique 唯一索引 ,如果設為True,這列唯一
index 常規索引, 如果設為True,創建索引,提升查詢效率
nullable 是否可以為null 默認True
default 默認值

(4)在flask中使用ORM模型

下面我們使用ORM模型

from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:20111673@127.0.0.1:3306/demo'
db = SQLAlchemy(app)  #

manager = Manager(app)

#創建User用戶,表名為user
class User(db.Model):
    __table__name = 'user'
    id = db.Column(db.Integer,primary_key=True)
    username = db.Column(db.String(20),index=True)
    sex = db.Column(db.Boolean,default=True)
    info = db.Column(db.String(50))

# 定義一個視圖函數
@app.route('/create')
def create():
    # db.drop_all()  #刪除僅為模型表
    db.create_all()  #創建模型表
    return '創建成功'

if __name__ == '__main__':
    manager.run()

(5)增加數據

添加數據方式1

#方式1
# sqlalchemy默認開啟了事務處理
@app.route('/insert/')
def insert():
    try:
        u = User(username='WANGWU',info='personal WANGWU message')
        db.session.add(u)  #添加數據對象
        db.session.commit()  #事務提交
    except:
        db.session.rollback()#事務回滾
    return '添加單條數據!'

@app.route('/insertMany/')
def insertMany():
    u1 = User(username='name1',info='personal name1 message')
    u2 = User(username='name2',info='personal name2 message')
    db.session.add_all([u1,u2]) #以add_all(數據對象列表)
    db.session.commit() #
    return '添加多條數據!'

添加數據方式2

#方式2
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True  #在app設置里開啟自動提交
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  #關閉數據追蹤,避免內存資源浪費

@app.route('/insertMany/')
def insertMany():
    u1 = User(username='name1',info='personal name1 message')
    u2 = User(username='name2',info='personal name2 message')
    db.session.add_all([u1,u2])
    return '提交多條數據'

(6)更新與刪除

# 類名.query  返回對應的查詢集
# 類名.query.get(查詢條件)  返回對應的查詢對象
@app.route('/update/')
def update():
    u = User.query.get(1)
    u.username = 'update name'  #更新內容
    db.session.add(u)   #進行添加
    return 'update'

# 刪除數據
@app.route('/delete/')
def delete():
    u = User.query.get(2)  #找到對應的查詢集對象
    db.session.delete(u)  # 刪除對應的u對象
    return 'delete id=2'

(7) 拆分MVT

目錄結構

project/
	manage.py  #啟動項存放
    ext.py  #作為當前sqlalchemy擴展
    settings.py  #配置存放
    app/
    	__init__.py
    	models.py  #應用models.py
        views.py   #應用視圖views.py
    templates/     #模板目錄
    static/  #靜態文件目錄

ext.py SQLAlchemy擴展

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()   #實例化db對象

藍本view view.py視圖函數

from flask import Blueprint
from .models import User
from ext import db
#創建藍本view
view = Blueprint('view',__name__)
#定義視圖函數
@view.route('/')
def index():
    return 'index'

@view.route('/insert/')
def insert():
    u = User(username='張三',info='個人信息')
    db.session.add(u)
    return 'insert success'

藍本view models.py模型類

from ext import db  #導入db
#構建User模型類
class User(db.Model,Base):
    __table__name = 'user'
    id = db.Column(db.Integer,primary_key=True)
    username = db.Column(db.String(20),index=True)
    sex = db.Column(db.Boolean,default=True)
    info = db.Column(db.String(50))

manage.py啟動項

from flask import Flask
from flask_script import Manager
from ext import db
import settings
from app.view import view

app = Flask(__name__)
#將系統配置項Config類加載到app
app.config.from_object(settings.Config)
#通過db對象將app初始化
db.init_app(app)
#將藍圖view注冊進app
app.register_blueprint(view)
manager = Manager(app)

if __name__ == '__main__':
    manager.run()

setting.py配置文件

class Config:
    #設置mysql+pymysql的連接
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:20111673@127.0.0.1:3306/demo'
    #加密設置
    SECRETE_KEY = 'secret_key'
    #關閉數據追蹤
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    #開啟提交
    SQLALCHEMY_COMMIT_ON_TEARDOWN = True

前面我們采用系統的每次自動提交session 即SQLALCHEMY_COMMIT_ON_TEARDOWN

但是如果想自己定義提交方式,同時不想傳入關鍵字參數,那么該怎樣入手呢?這里提供一種思路

(8) 自定義增刪改類

我們對模型類進行了修改,models.py 內容如下:

from ext import db
#定義了base基類
class Base:
    def save(self):
        try:
            db.session.add(self)  #self實例化對象代表就是u對象
            db.session.commit()  
        except:
            db.session.rollback()
    #定義靜態類方法接收List參數        
    @staticmethod
    def save_all(List):
        try:
            db.session.add_all(List)
            db.session.commit()
        except:
            db.session.rollback()
	#定義刪除方法
    def delete(self):
        try:
            db.session.delete(self)  
            db.session.commit()  
        except:
            db.session.rollback()
#定義模型user類
class User(db.Model,Base):
    __table__name = 'user'
    id = db.Column(db.Integer,primary_key=True)
    username = db.Column(db.String(20),index=True)
    sex = db.Column(db.Boolean,default=True)
    info = db.Column(db.String(50))
	#
    def __init__(self,username='',info='',sex=True):
        self.username = username
        self.info = info
        self.sex = sex
#注意:
#原實例化:  u = User(username='張三',info='個人信息')
#現實例化: u = User('李四','李四個人信息')

在views.py中使用

from flask import Blueprint
from .models import User
from ext import db

view = Blueprint('view',__name__)

@view.route('/')
def index():
    return 'index'
#插入單條數據
@view.route('/insert/')
def insert():
    # u = User(username='test',info='default')
    u = User('xiaomeng','default')
    u.save()
    db.session.add(u)
    return 'insert success'
#保存多條數據
@view.route('/saveMany/')
def saveMany():
    u1 = User('zhan123','default123')
    u2 = User('li123','default message')
    User.save_all([u1,u2])
    return 'add many'
#刪除數據
@view.route('/delete/')
def delete():
    u = User.query.get(1)  #獲取查詢集
    u.delete()
    return 'delete message'

其他都不做改變,基本思路是封裝到類,通過多繼承來實現方法的調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM