使用 SQLAlchemy ORM 查詢數據的時候,如果需要的獲取的記錄按選條件進行篩選,可以參考本文介紹的相關方法。不存在什麼技巧,需要的是熟悉而已。使用我經常用的數據源 Sample Data。推薦使用 jupyter notebook 進行交互測試。
使用 SQLAlchemy ORM,涉及到 engine, session 等對象。在查詢前,先準備好如下代碼:
from sqlalchemy import create_engine
from sqlalchemy import Column, String, Integer, and_, or_
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql+pymysql://root:pwd@localhost:3306/stonetestdb?charset=utf8')
Base = declarative_base(engine)
Session = sessionmaker(engine)
session = Session()
class EmpMaster(Base):
__tablename__ = 'emp_master'
EMP_ID = Column(Integer, primary_key=True)
GENDER = Column(String(10))
AGE = Column(Integer)
EMAIL = Column(String(50))
PHONE_NR = Column(String(20))
EDUCATION = Column(String(20))
MARITAL_STAT = Column(String(20))
NR_OF_CHILDREN = Column(Integer)
def __str__(self):
return '<Employee({}, {}, {}, {}, {}, {}, {}, {}, {})>'.format(
self.EMP_ID,
self.GENDER,
self.AGE,
self.EMAIL,
self.EMAIL,
self.PHONE_NR,
self.EDUCATION,
self.MARITAL_STAT,
self.NR_OF_CHILDREN
)
def print_emps(emps):
for emp in emps:
print(emp)
在 EmpMaster
類中,定義 __str__()
方法的作用是方便調用代碼的輸出顯示。print_emps()
方法是打印多個 EmpMaster 時候減少代碼量。
按 primary key 篩選
第一種方法,使用 Query
對象的 get()
方法。
# filter by primary key
emp = session.query(EmpMaster).get(1001)
print(emp)
session.query()
方法返回的是 sqlalchemy.orm.query.Query
對象實例。調用 Query 對象的 get()
方法,按 primary key 獲取記錄。
第二種方法,使用 Query 對象的 filter_by()
方法。filter_by()
方法的參數爲關鍵字,用起來相對簡單,但不夠強大。
# fiter by primary key method 2
emp = session.query(EmpMaster).filter_by(EMP_ID = 1001).first()
print(emp)
方法三,使用 Query 對象的 fitter()
方法。這個方法的參數是 sqlalchemy ORM 的 SQL Expression,用起來相對複雜點,但非常強大。爲什麼會強大,稍後結合實例解釋。比如剛纔的按 primary key 進行篩選,用 filter_by()
方法是這樣的:
emp = session.query(EmpMaster).filter(
EmpMaster.EMP_ID == 1001
).first()
print(emp)
filter()
方法的參數是 sql expression,比如本例中 EmpMaster.EMP_ID
是一個 Column,通過查看 Column 的源碼,我們可以看到 Column 對象有 like, in_, contains 等方法,所以可以表達複雜的篩選條件。
equal 和 not equal
後面我們都用 filter()
方法來學習如何表達篩選條件。剛纔已經演示了 equal (==),如果要表達 not equal,使用 !=
操作符:
emps = session.query(EmpMaster).filter(
EmpMaster.EMP_ID != 1001
).limit(3).all()
print_emps(emps)
AND 條件
如果有多個篩選條件,並且這些條件之間是 AND 關係,表達方法有兩種。一種是條件之間用逗號分開,默認的關係就是 AND; 第二種方法是用 and_
:
emps = session.query(EmpMaster).filter(
EmpMaster.EMP_ID <= 1009, EmpMaster.GENDER == 'Female'
).all()
print_emps(emps)
或者:
emps = session.query(EmpMaster).filter(
and_(EmpMaster.EMP_ID <= 1009, EmpMaster.GENDER == 'Female')
).all()
print_emps(emps)
注意 and_
需要導入。
OR 條件
或者條件需要使用 or_
,需要導入。
emps = session.query(EmpMaster).filter(
or_(EmpMaster.GENDER == 'Female', EmpMaster.NR_OF_CHILDREN == 0)
).all()
print_emps(emps)
模糊查找
模糊查找有兩種方法:contains 或者 like。比如我們要查詢 EMAIL 中含有 west 字符串的人員:
emps = session.query(EmpMaster).filter(
EmpMaster.EMAIL.contains('west')
).all()
print_emps(emps)
或者:
emps = session.query(EmpMaster).filter(
EmpMaster.EMAIL.like('%west%')
).all()
print_emps(emps)
IN
如果要從幾個字符串中選擇,作爲查詢條件,使用 in_
關鍵字,參數是一個 list。比如下面的查詢表示查找學歷爲碩士或博士的員工:
emps = session.query(EmpMaster).filter(
EmpMaster.EDUCATION.in_(['Doctorial', 'Master'])
).limit(3).all()
print_emps(emps)