當(dāng)我們習(xí)慣 Flask-SQLAlchemy 對(duì)數(shù)據(jù)庫進(jìn)行 CRUD 操作后荞估,就很難再回到基于原生 SQL 的代碼編寫了杈抢。
我們先來看 Read 操作。用實(shí)際的例子來說明用法纸巷,數(shù)據(jù)還是之前經(jīng)常用到的 emp_master 棒掠,
基于上一篇 Flask 工程的文件結(jié)構(gòu)者祖,在 models.py
中定義的 Class 如下:
class EmpMaster(db.Model):
emp_id = db.Column(db.Integer, primary_key=True)
gender = db.Column(db.String(10), nullable=False)
age = db.Column(db.Integer)
email = db.Column(db.String(50))
phone_nr = db.Column(db.String(20))
education = db.Column(db.String(20))
marital_stat = db.Column(db.String(20))
nr_of_children = db.Column(db.Integer)
def __repr__(self):
return '<emp_master %r>' % 'id:{}'.format(self.emp_id)
查詢數(shù)據(jù)
查詢所有數(shù)據(jù)
from app.models import db, EmpMaster
print (EmpMaster.query.all())
EmpMaster.query
得到的是 BaseQuery
對(duì)象的實(shí)例立莉,對(duì)于 BaseQuery
類,SQLAlchemy 提供了一些查詢方法用于獲得你想要的查詢對(duì)象七问,比如 all()
方法以 list
(列表) 的形式返回所有的查詢結(jié)果蜓耻。
根據(jù)主鍵查詢數(shù)據(jù)
get()
或 get_or_404()
方法根據(jù)主鍵來查詢數(shù)據(jù)。get()
方法返回 model 的實(shí)例械巡,如果找不到刹淌,則返回 None;而 get_or_404()
則返回 Not found
的錯(cuò)誤響應(yīng)讥耗。
EmpMaster.query.get(1001) # 1001 是主鍵
篩選/過濾數(shù)據(jù)
篩選過濾數(shù)據(jù)通過 filter_by()
或 filter()
方法有勾。假設(shè)我們想查詢所有女性雇員,可以這樣做:
emps = EmpMaster.query.filter_by(gender='Female').all()
if len(emps) > 0:
for emp in emps:
print(emp.emp_id, emp.gender, emp.email, emp.education)
else:
print ('No data.')
filter_by()
方法返回的是 BaseQuery
對(duì)象實(shí)例古程,參數(shù)是關(guān)鍵字表達(dá)式 (keyword expression)蔼卡,可以多個(gè)字段,多個(gè)字段之間為 and 關(guān)系挣磨。比如要查詢所有女性雇逞,并且學(xué)歷為 Bachelor 的員工:
emps = EmpMaster.query.filter_by(gender='Female', education='Bachelor11').all()
if len(emps) > 0:
for emp in emps:
print(emp.emp_id, emp.gender, emp.email, emp.education)
else:
print ('No data.')
更為靈活的方式是通過 filter()
方法,與 filter_by()
方法不同的是茁裙,filter()
方法的參數(shù)是 SQL Expression塘砸。舉幾個(gè)例子來說明。
查找所有 education 為 Bachelor 的員工:
emps = EmpMaster.query.filter(EmpMaster.education == 'Bachelor').all()
for emp in emps:
print (emp)
如果用 filter_by()
方法晤锥,是這樣的:
emps = EmpMaster.query.filter_by(education='Bachelor').all()
看出區(qū)別來了吧掉蔬。下表列示了常見條件的寫法廊宪。
條件 | 示例 |
---|---|
等于 | query.filter(EmpMaster.education == 'Bachelor') |
不等于 | query.filter(EmpMaster.education != 'Bachelor') |
LIKE | query.filter(EmpMaster.email.like('s%')) |
IN | query.filter(EmpMaster.education.in_(['Master', 'Bachelor'])) |
NOT IN | query.filter(~EmpMaster.education.in_(['Master', 'Bachelor'])) |
IS NULL | query.filter(EmpMaster.education == None) |
IS NOT NULL | query.filter(EmpMaster.education != None) |
AND 條件:
EmpMaster.query.filter(EmpMaster.gender=='Female', EmpMaster.education=='Bachelor')
# 或者
from sqlalchemy import and_
emps = EmpMaster.query.filter(
and_(EmpMaster.gender=='Female', EmpMaster.education=='Bachelor')).all()
OR 條件
from sqlalchemy import or_
emps = EmpMaster.query.filter(
or_(EmpMaster.marital_stat=='Single', EmpMaster.nr_of_children==0))
Create
SQLAlchemy 有一個(gè) session 對(duì)象,代表臨時(shí)存儲(chǔ)區(qū)女轿,數(shù)據(jù)的變動(dòng)提交到 session 后挤忙,需要調(diào)用 commit()
將修改提交到數(shù)據(jù)庫,或者 rollback()
撤銷未提交的修改谈喳。
from app.models import db, EmpMaster
from app import create_app
app = create_app()
new_emp = EmpMaster(
emp_id = 9001,
gender = 'Female',
age = 18,
email = 'test@qq.com',
phone_nr = '13800138000',
education = 'Master',
marital_stat = 'Single',
nr_of_children = 0
)
db.session.add(new_emp)
db.session.commit()
可以使用 add_all()
方法批量創(chuàng)建記錄:
emp1 = EmpMaster(...)
emp2 = EmpMaster(...)
db.session.add_all([emp1, emp2])
db.session.commit()
Update
Update 記錄需要先定位到某記錄,然后對(duì)需要的字段賦值后戈泼,然后調(diào)用 commit()
方法提交修改:
emp = EmpMaster.query.get(9001)
emp.email = 'e9001@qq.com'
db.session.commit()
Delete
Delete 記錄先定位到某記錄婿禽,然后調(diào)用 delete()
方法發(fā)送刪除指到 session,最后調(diào)用 commit()
將請(qǐng)求提交到數(shù)據(jù)庫大猛。
emp = EmpMaster.query.get(9001)
db.session.delete(emp)
db.session.commit()