SQLAlchemy ORM查詢常見篩選條件的表示方法

使用 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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章