一、配置數(shù)據(jù)庫(kù)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/flaskdb7'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Flase
app.init_app(app)
二、創(chuàng)建模型
from flask_script import SQLAlchemy
# 創(chuàng)建一個(gè)sqlalchemy對(duì)象
db = SQLAlchemy()
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(31), unique=True, nullable=True)
phone = db.Column(db.String(11), nullable=True)
age = db.Column(db.Integer, nullable=Flase)
gender = db.Column(db.Integer, default=1)
# flask默認(rèn)表明就是模型名小寫,如果你不需要改變表明就可以不用設(shè)置
__tablename__ = 'tb_student'
??模型定義中支持的數(shù)據(jù)類型
| 類型 | 說(shuō)明 |
|---|---|
| Integer | 整數(shù) |
| String | 字符串類型(在某些數(shù)據(jù)庫(kù)中是可選的如:PostgreSQL) |
| Text | 長(zhǎng)文本 |
| DateTime | 日期和時(shí)間,表示為Python中的datetime對(duì)象 |
| float | 浮點(diǎn)數(shù) |
| Boolean | 布爾值 |
三、對(duì)數(shù)據(jù)庫(kù)進(jìn)行CRUD操作
3.1 增加數(shù)據(jù)
在flask中增加數(shù)據(jù)需要用到SQLAlchemy的一個(gè)session回話,這里的session并不是flask請(qǐng)求和響應(yīng)的回話session
添加數(shù)據(jù)需要用到
session.add(對(duì)象) # 將對(duì)象添加到session中
session.commit() # 提交session(可以理解成提交事務(wù),如果未提交,則所有數(shù)據(jù)都未添加到數(shù)據(jù)庫(kù))
a. 增加一條
# 獲取一個(gè)學(xué)生對(duì)象
stu = Student()
stu.name = '小明'
stu.phone = '12345612345'
stu.age = 16
# 添加對(duì)象到session中
db.session.add(stu)
# 提交事務(wù)
db.session.commit()
b. 增加多條
通過(guò)db.session.add_all()實(shí)現(xiàn)
stus = []
# 循環(huán)產(chǎn)生多個(gè)學(xué)生對(duì)象
for _ in range(10):
stu = Student()
# 這里可能會(huì)重復(fù)
stu.name = '小明%s' % random.randint(1, 1000)
stu.age = random.randint(16, 28)
stu.phone = '12345123451'
# 把視圖添加到stus列表中
stus.append(stu)
# 調(diào)用add_all()方法
db.session.add_all(stus)
# 提交事務(wù)
db.session.commit()
3.2 修改數(shù)據(jù)
修改類似于添加,先過(guò)濾出需要修改的學(xué)生對(duì)象,然后在修改相應(yīng)的字段
# 通過(guò)filter過(guò)濾出對(duì)象
stu = Student.query.filter(Student.id == id).first()
stu.name = username
stu.phone = phone
stu.age = age
# 將對(duì)象添加到sqlalchemy中
db.session.add(stu)
# 提交事務(wù)
db.session.commit()
修改數(shù)據(jù)時(shí) db.session.add(stu) 可以不寫
3.3 刪除數(shù)據(jù)
通過(guò)調(diào)用delete方法
db.session.delete(對(duì)象)
# 過(guò)濾出學(xué)生對(duì)象
stu = Student.query.fliter(Student.id == id).firts()
# 調(diào)用delete方法
db.session.delete(stu)
# 提交事務(wù)
# db.session.commit()
3.4 查詢操作
3.4.1 filter和get過(guò)濾
# 查詢指定id的學(xué)生信息 filter()
# 模型.query.filter(模型.字段 == 值)
stu = Student.query.filter(Student.id == 3).first()
# 查詢指定id的學(xué)生信息 filter_by()
stu1 = Student.query.filter_by(id=3).first()
# 查詢指定id的學(xué)生信息 get(pk), 只能查詢主鍵,只能查出一條數(shù)據(jù),返回一個(gè)查詢對(duì)象
# 主鍵不存在不會(huì)報(bào)錯(cuò),這與Django有區(qū)別
stu3 = Student.query.get(3)
在filter過(guò)濾中
first() 獲取查詢集中的第一個(gè)查詢對(duì)象
last() 獲取查詢集中的最后一個(gè)查詢對(duì)象
3.4.2 查詢所有
# 查詢所有的數(shù)據(jù) all(), 返回一個(gè)列表
stus = Student.query.all()
3.4.3 對(duì)查詢集進(jìn)行排序
# 排序 升序 默認(rèn)就是升序 order_by('字段/-字段') order_by('字段 asc/desc')
stus = Student.query.order_by('age')
stus = Student.query.order_by('age asc')
# 排序 降序
stus = Student.query.order_by('-age')
stus = Student.query.order_by('age desc')
# 實(shí)現(xiàn)簡(jiǎn)單分頁(yè) offset(m).limit(n) 跳過(guò)每條看(截取)n條數(shù)據(jù)
stus = Student.query.offset(0).limit(2)
3.4.3 模糊查詢
# contains('字符') 包含
stus = Student.query.filter(Student.name.contains('哈')).all()
# 以什么開頭 startswith('字符')
stus = Student.query.filter(Student.name.startswith('哈')).all()
# 以什么結(jié)尾 endswith('字符')
stus = Student.query.filter(Student.name.endswith('4')).all()
# 第二位以'明'的學(xué)生 like() _(下劃線): 匹配一個(gè)字符,% 通配符匹配多個(gè)字符
stus = Student.query.filter(Student.name.like('_明%')).all()
# 查詢?cè)谀硞€(gè)范圍內(nèi)的學(xué)生信息 模型.id.in_(列表)
stus = Student.query.filter(Student.id.in_([1, 5, 16, 18]))
3.4.4 條件和邏輯運(yùn)算組合查詢
# 條件查詢
# lt le gt ge 小于、小于等于、大于、大于等于
stus = Student.query.filter(Student.age.__le__(22)).all()
# 條件查詢可以寫 < <= > >= ==
stus = Student.query.filter(Student.age <= 22).all()
# 條件組合查詢
# 年齡小于22, 姓名以6結(jié)束
# 且關(guān)系可以用鏈?zhǔn)竭^(guò)濾的方法實(shí)現(xiàn)
stus = Student.query.filter(Student.age < 22).filter(Student.name.endswith('0')).all()
# 且 關(guān)系,用逗號(hào)隔開也是且關(guān)系
stus = Student.query.filter(Student.age < 22, Student.name.endswith('0')).all()
除了上面的方法還可以用sqlalchemy庫(kù)里面提供的方法實(shí)現(xiàn) 且、或、非關(guān)系
# from sqlalchemy import and_, or_, not_
# 且 and_
stus = Student.query.filter(and_(Student.age < 22,Student.name.endswith('0'))).all()
# 或 or_
stus = Student.query.filter(or_(Student.age < 22,Student.name.endswith('0'))).all()
# 非 not_
stus = Student.query.filter(not_(Student.age == 22)).all()
3.4.5 使用paginator進(jìn)行分頁(yè)
# paginator分頁(yè)
# 獲取學(xué)生信息,all()返回一個(gè)列表
students = Student.query.all()
# 從get請(qǐng)求中獲取頁(yè)碼,也就是請(qǐng)求第幾頁(yè)
page = int(request.args.get('page', 1))
# 將上面查詢出的所有student列表丟給paginate分頁(yè)
paginate = Student.query.paginate(page, 5)
# 在paginate方法中
paginate(頁(yè)碼, 每頁(yè)數(shù)據(jù)條數(shù)據(jù))
# 獲取當(dāng)前頁(yè)(page)的數(shù)據(jù)列表,該方法返回一個(gè)列表,這與Django不一樣,如果不用items,paginate是一個(gè)不能迭代的對(duì)象
students = paginate.items
??flask中的paginate分頁(yè)中的一些方法
| 方法 | 說(shuō)明 |
|---|---|
| paginate.has_prev | 判斷是否有上一頁(yè) |
| paginate.has._next | 判斷是否有下一頁(yè) |
| paginate.pages | 返回總的頁(yè)數(shù) |
| paginate.page_num | 返回當(dāng)前頁(yè)的頁(yè)碼 |
| paginate.prev_num | 返回上一頁(yè)的頁(yè)碼 |
| paginate.next_num | 返回下一頁(yè)的頁(yè)碼 |
| paginate.iter_pages() | 返回總的頁(yè)碼,可迭代 |
| paginate.total | 返回總的數(shù)據(jù)條數(shù) |
四、模板解析地址
4.1 無(wú)參數(shù)的反向解析url
假設(shè)藍(lán)圖對(duì)象為
blue = Blueprint('app', __name__)
則反向解析
{{ url_for('app.需要跳轉(zhuǎn)到的函數(shù)名') }}
{{ url_for('app.stu_list') }}
4.2 有參數(shù)的反向解析url
{{ url_for('藍(lán)圖對(duì)象第一個(gè)參數(shù).需要跳轉(zhuǎn)到的函數(shù)名', 參數(shù)名 = 值) }}
# 編輯id=3的學(xué)生信息
{{ url_for('app.edit_stu', id=3) }}
get方式向服務(wù)器提交數(shù)據(jù)時(shí)的反向解析
{{ url_for('藍(lán)圖的第一個(gè)參數(shù).需要跳轉(zhuǎn)到的函數(shù)名') }}?參數(shù)名=值
如分頁(yè)中需要看第i頁(yè)則如下:
{{ url_for('app.stu_list')}}?page={{ i }}