使用 SQLAlchemy ORM 查詢數(shù)據(jù)的時候户誓,如果需要的獲取的記錄按選條件進行篩選,可以參考本文介紹的相關(guān)方法其掂。不存在什么技巧脖隶,需要的是熟悉而已扁耐。使用我經(jīng)常用的數(shù)據(jù)源 Sample Data。推薦使用 jupyter notebook 進行交互測試浩村。
使用 SQLAlchemy ORM做葵,涉及到 engine, session 等對象。在查詢前心墅,先準(zhǔn)備好如下代碼:
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__()
方法的作用是方便調(diào)用代碼的輸出顯示。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
對象實例铐姚。調(diào)用 Query 對象的 get()
方法策肝,按 primary key 獲取記錄。
第二種方法隐绵,使用 Query 對象的 filter_by()
方法之众。filter_by()
方法的參數(shù)為關(guān)鍵字,用起來相對簡單依许,但不夠強大棺禾。
# fiter by primary key method 2
emp = session.query(EmpMaster).filter_by(EMP_ID = 1001).first()
print(emp)
方法三,使用 Query 對象的 filter()
方法峭跳。這個方法的參數(shù)是 sqlalchemy ORM 的 SQL Expression膘婶,用起來相對復(fù)雜點,但非常強大蛀醉。為什么會強大悬襟,稍后結(jié)合實例解釋。比如剛才的按 primary key 進行篩選拯刁,用 filter_by()
方法是這樣的:
emp = session.query(EmpMaster).filter(
EmpMaster.EMP_ID == 1001
).first()
print(emp)
filter()
方法的參數(shù)是 sql expression脊岳,比如本例中 EmpMaster.EMP_ID
是一個 Column,通過查看 Column 的源碼垛玻,我們可以看到 Column 對象有 like, in_, contains 等方法割捅,所以可以表達復(fù)雜的篩選條件。
equal 和 not equal
后面我們都用 filter()
方法來學(xué)習(xí)如何表達篩選條件夭谤。剛才已經(jīng)演示了 equal (==),如果要表達 not equal巫糙,使用 !=
操作符:
emps = session.query(EmpMaster).filter(
EmpMaster.EMP_ID != 1001
).limit(3).all()
print_emps(emps)
AND 條件
如果有多個篩選條件朗儒,并且這些條件之間是 AND 關(guān)系,表達方法有兩種。一種是條件之間用逗號分開醉锄,默認的關(guān)系就是 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_
需要導(dǎo)入乏悄。
OR 條件
或者條件需要使用 or_
,需要導(dǎo)入恳不。
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_
關(guān)鍵字规求,參數(shù)是一個 list。比如下面的查詢表示查找學(xué)歷為碩士或博士的員工:
emps = session.query(EmpMaster).filter(
EmpMaster.EDUCATION.in_(['Doctorial', 'Master'])
).limit(3).all()
print_emps(emps)