1.帶條件查詢
查詢是最常用的,對於各種查詢我們必須要十分清楚,首先是帶條件的查詢
#帶條件查詢 rows = session.query(User).filter_by(username='jingqi').all() print(rows) rows1 = session.query(User).filter(User.username=='jingqi').all() print(rows1) rows2 = session.query(User.username).filter(User.username=='jingqi').all() print(rows2) rows3 = session.query(User.username).filter(User.username=='jingqi') print(rows3)
`filter_by`和`filter`都是過濾條件,只是用法有區別`filter_by`里面不能用`!= `還有`> <` 等等,所有`filter`用得更多,`filter_by`只能用`=`。
前兩個查詢的是`User`,所以返回結果也是一個對象,但是`rows2`查詢的是屬性值,所以返回的是屬性值。
`rows3`可以看到`SQLAlchemy `轉成的`SQL`語句,`SQLAlchemy`最后都是會轉成`SQL`語句,通過這個方法可以查看原生`SQL`,甚至有些時候我們需要把`SQLAlchemy`轉成的`SQL`交給DBA審查,合適的才能使用。
查詢要知道查詢結果的返回怎樣的數據
print( session.query(User).filter(User.username=='jingqi').all() ) print( session.query(User).filter(User.username=='jingqi').first()) print( session.query(User).filter(User.username=='jingqi').one())#結果為一個時正常,多了就報錯 print( session.query(User).get(2))#通過id查詢
上面三條記錄,第一個查出所有符合條件的記錄,第二個查出所有符合記錄的第一條記錄,第三個返回一個對象,如果結果有多條就會報錯,第四個通過主鍵獲取記錄
除此之外,我們偶爾也會需要限制返回的結果數量
#限制查詢返回結果 print( session.query(User).filter(User.username!='jingqi').limit(2).all()) print( session.query(User).filter(User.username!='jingqi').offset(2).all()) print( session.query(User).filter(User.username!='jingqi').slice(2,3).all())
#可以排序之后再進行限制
from sqlalchemy import desc
print( session.query(User).filter(User.username!='budong').order_by(User.username).all())
print( session.query(User).filter(User.username!='budong').order_by(desc(User.username)).slice(1,3).all())
第一個是限制返回條數,從第一條開始;第二個是從第三條開始返回查詢結果;第三個是切片返回記錄。
`order_by`默認是順序,`desc`是降序。
還有其他的帶條件查詢
#不等於 print( session.query(User).filter(User.username!='jingqi').all() ) #模糊匹配 like print( session.query(User).filter(User.username.like('jingqi')).all() ) print( session.query(User).filter(User.username.notlike('jingqi')).all() ) #成員屬於 in_ print( session.query(User).filter(User.username.in_(['jingqi','jingqi1'])).all() ) #成員不屬於 notin_ print( session.query(User).filter(User.username.notin_(['jingqi','jingqi2'])).all() ) #空判斷 print( session.query(User).filter(User.username==None).all() ) print( session.query(User).filter(User.username.is_(None)).all() ) print( session.query(User).filter(User.username.isnot(None)).all() ) #多條件 print( session.query(User).filter(User.username.isnot(None),User.password=='qwe123').all() ) #選擇條件 from sqlalchemy import or_,and_,all_,any_ print( session.query(User).filter(or_(User.username=='jingqi',User.password=='qwe123')).all() ) print( session.query(User).filter(and_(User.username=='jingqi2',User.password=='111')).all() )
以上是各種帶條件的查詢,大家知道怎么使用,但是需要注意的是,所以的模糊匹配是十分耗費時間的,能不用就盡量不要用。
當然還有聚合函數的使用
from sqlalchemy import func,extract print( session.query(User.password,func.count(User.id)).group_by(User.password).all() ) print( session.query(User.password,func.count(User.id)).group_by(User.password).having(func.count(User.id)>1).all() ) print( session.query(User.password,func.sum(User.id)).group_by(User.password).all() ) print( session.query(User.password,func.max(User.id)).group_by(User.password).all() ) print( session.query(User.password,func.min(User.id)).group_by(User.password).all() ) #使用extract提取時間中的分鍾或者天來分組 print( session.query(extract('minute', User.creatime).label('minute'),func.count('*').label('count')).group_by('minute').all() ) print( session.query(extract('day', User.creatime).label('day'),func.count('*').label('count')).group_by('day').all() )
這里只是告訴大家的用法,其中`group_by`是分組,如果要使用聚合函數,就必須導入`func`,`label`是取別名的意思 。
2.表關系查詢
對於有表關系的,也有些不同的查詢,首先我們來建立一個有外鍵關系的表
from sqlalchemy.orm import relationship from sqlalchemy import ForeignKey class UserDetails(Base): __tablename__ = 'user_details' id = Column(Integer,primary_key=True,autoincrement=True) id_card = Column(Integer,nullable=False,unique=True) lost_login = Column(DateTime) login_num = Column(Integer,default=0) user_id = Column(Integer,ForeignKey('user.id')) userdetail_for_foreignkey = relationship('User',backref='details',uselist=False,cascade='all') def __repr__(self): return '<UserDetails(id=%s,id_card=%s,lost_login=%s,login_num=%s,user_id=%s)>'%( self.id, self.id_card, self.login_login, self.login_num, self.user_id )
這里要注意`relationship`默認是一對多的關系,使用`uselist=False`則表示一對一的關系,`cascade` 是自動關系處理,就和MySQL中的`ON DELETE`類似,但是有區別,參數選項如下:
`cascade` 所有的可選字符串項是:
- *all* , 所有操作都會自動處理到關聯對象上.
- *save-update* , 關聯對象自動添加到會話.
- *delete* , 關聯對象自動從會話中刪除.
- *delete-orphan* , 屬性中去掉關聯對象, 則會話中會自動刪除關聯對象.
- *merge* , `session.merge()` 時會處理關聯對象.
- *refresh-expire* , `session.expire()` 時會處理關聯對象.
- *expunge* , `session.expunge()` 時會處理關聯對象.
有如上的表關系之后,查詢可以十分方便
#表關系查詢 row = session.query(UserDetails).all() print(row,dir(row[0])) row = session.query(User).filter(User.id==1).first() print(row,dir(row)) print(row.details) print(row.details[0].lost_login)
`relationship`會在`User`表里面添加一個屬性,通過這個屬性就可以查詢對應的`user_details`表中的所有字段。省去了很多的代碼。
3.多表查詢
多表查詢也是必須要掌握的知識點。以下是常見的幾種表關聯方式,需要熟練掌握。
#多表查詢 print( session.query(UserDetails,User).all() ) #這個是 cross join print( session.query(UserDetails,User).filter(User.id==UserDetails.id).all() ) #這是也是cross join 但是加上了where條件 print( session.query(User.username,UserDetails.lost_login).join(UserDetails,UserDetails.id==User.id).all() ) #這個是inner join print( session.query(User.username,UserDetails.lost_login).outerjoin(UserDetails,UserDetails.id==User.id).all() ) #這個才是左連接,sqlalchemy沒有右連接 q1 = session.query(User.id) q2 = session.query(UserDetails.id) print(q1.union(q2).all()) #這個是union關聯
除了上面的幾種關聯方式,子表查詢也是用得很多的,也是要掌握的
from sqlalchemy import all_,any_ sql_0 = session.query(UserDetails.lost_login).subquery() #這是聲明一個子表 print( session.query(User).filter((User.creatime > all_(sql_0)) ).all() ) print( session.query(User).filter((User.creatime > any_(sql_0)) ).all() )
注意`any_`和`all_`的區別,`all_`要求的是所有都滿足,`any_`只需要有滿足的就行。
4.原生SQL的查詢以及其他使用
再次強調,使用`ORM`或者原生`SQL`沒有絕對的那個好一點,怎么方便怎么使用。
#第一步寫好原生的sql,如果需要傳遞參數,可以使用字符串拼接的方式 sql_1 = """ select * from `user` """ #第二步執行,得到返回的結果 row = session.execute(sql_1) print(row,dir(row)) #第三步,自己控制得到數據的方式 print( row.fetchone() ) print( row.fetchmany() ) print( row.fetchall() ) #也可以循環獲得 for i in row: print('===',i)
本次介紹先到這里,后續會在項目中使用,敬請期待