Web程式開發中最重要的莫過於關係型資料庫,即SQL 資料庫,另外文檔資料庫(如 mongodb)、鍵值對資料庫(如 redis)慢慢變得流行. 原因 : 我們不直接使用這些資料庫引擎提供的 Python 包,而是使用對象關係映射(Object Relational Mapper, ORM)框架 ...
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 |
註意:
- username 和 password 表示登錄資料庫的用戶名和密碼
- hostname 表示 SQL 服務所在的主機,可以是本地主機(localhost)也可以是遠程伺服器
- database 表示要使用的資料庫 , SQLite 資料庫不需要使用伺服器,它使用硬碟上的文件名作為 database
ORM使用的優點:
- 增加少sql的重覆使用率
- 使表更加的可讀性
- 可移植性
(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:[email protected]: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:[email protected]: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'
其他都不做改變,基本思路是封裝到類,通過多繼承來實現方法的調用。