使用 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)