結果查詢sql
上節課使用query從數據庫中查詢到告終果,可是query返回的對象是直接可用的嗎?數據庫
首先導入模塊session
from connect import session from user_modules import User
query返回對象函數
rs = session.query(User) print(rs) for i in rs: print(i) #---------------------------------- #根據返回結果來看, rs 是一個 Query 對象,打印出來能夠看到轉化的 SQL rs = session.query(User).filter(User.username=='塔卡')
#all 是返回全部符合條件的數據 rs = session.query(User).all() #查詢全部數據,返回一個列表 print(rs) print(rs[0].username) #屬性訪問
#first 是返回全部符合條件數據的第一條數據 rs = session.query(User).first() #查詢第一條數據
#[0] 和 first 相似,可是若是沒有符合條件的數據則會報錯 session.query(User).filter(User.username=='budong')[0]
#這裏,在 query 中查詢對象的某個屬性值 ( 對應爲查詢表中某個字段的值 ),返回的結果再也不是一個 Query 對象,而是一個列表 rs = session.query(User.username).filter(User.username == '塔卡').all()
#同理,可是 first 返回結果是一個元組 rs = session.query(User.username).filter(User.username == '塔卡').first()
#[0] 和 first 相似,可是若是沒有符合條件的數據則會報錯 session.query(User.username).filter(User.username=='budong')[0] #getattr(rs[0], 'username'), rs[0].username這兩種方式能夠取到具體的數據值 rs = session.query(User).filter(User.username=='budong').all() print(hasattr(rs,'username')) print(getattr(rs,'username','litao')) rs = session.query(User)[0:2] #索引取值 print(rs) # rs2 = session.query(User).filter(User.username=='塔卡').all() # print(rs,type(rs))
條件查詢一fetch
過濾函數spa
filter 是一個過濾函數,過濾條件均可以書寫在此函數中,不一樣的條件之間用 逗號 分隔code
filter_by 也是一個過濾函數,可是功能要弱一些orm
filter 和 filter_by 的區別對象
兩者都是 過濾函數,可是使用有以下差異:blog
1. filter 中須要添加 類對象,filter_by不須要
2. filter_by 中只能添加等於的條件,不能添加 不等於、大於小於等條件,filter沒有這個限制
rs = session.query(User.username).filter(User.username == '塔卡') rs2 = session.query(User.username).filter_by(username = '塔卡') print(rs)
like 和 notlike
like 是模糊查詢,和數據庫中的 like 用法同樣
notlike 和 like 做用相反
rs = session.query(User).filter(User.username.like('%塔%')).all() rs = session.query(User).filter(User.username.notlike('%塔%')).all()
in_ 和 notin_
in_ 和 notin_ 是範圍查找,參數爲列表
rs = session.query(User.username).filter(User.username.in_(['塔卡','小潑'])).all() rs = session.query(User.username).filter(User.username.notin_(['塔卡','小潑'])).all()
is_ 和 isnot
is_ 和 isnot 精確查找
rs = session.query(User).filter(User.username.is_(None)).all() rs = session.query(User).filter(User.username.isnot(None)).all() #判斷爲空還可使用: session.query(User.id).filter(User.username==None).all()
查詢結果數:限制查詢
all、limit、offset、slice、one
rs =session.query(User.username).all() print(rs) rs =session.query(User.username).limit(2).all() #限制數量查詢 rs =session.query(User.username).offset(2).all() #偏移量 rs =session.query(User.username).slice(1,4).all() #切片 #無論怎樣寫one只能查一條數據,若是有多條重複數據,會報錯 #sqlalchemy.orm.exc.MultipleResultsFound: Multiple rows were found for one() rs = session.query(User.username).filter(User.username == '李濤').one() print(rs)
排序:倒敘先進行導入desc
from sqlalchemy import desc rs = session.query(User.username,User.id).order_by(User.id).all() #升序排列 rs = session.query(User.username,User.id).order_by(desc(User.id)).all() #綜合使用 rs = session.query(User.username,User.id).order_by(desc(User.id)).filter(User.username == '李濤').all() print(rs)
聚合函數
func.count
使用函數時,須要導入 func, group_by 和 order_by 同樣,是能夠直接使用的,不須要導入
having 也能夠直接使用,使用方法也和 SQL 中使用相似
func.sum、func.max、func.min
extract
extract 提取對象中的數據,這裏提取分鐘,並把提取出來的結果用 label 命名別名,以後就可使用 group_by 來分組
count 裏面一樣可使用 *
or_
or_ 是或者的意思,和數據庫中的 or 同樣
# 分組查詢與聚合函數一塊兒使用 from sqlalchemy import func,extract,or_ # rs = session.query(User.password,func.count(User.id)).group_by(User.password).all() # rs = session.query(User.password,func.count(User.id)).group_by(User.password).having(func.count(User.id) >1).all() # print(rs) # rs = session.query(User.password,func.sum(User.id)).group_by(User.password).all() # rs = session.query(User.password,func.max(User.id)).group_by(User.password).all() # rs = session.query(User.password,func.min(User.id)).group_by(User.password).all() # print(rs) #extract # rs = session.query(extract('minute',User.create_time).label('minute'),func.count(User.id)).group_by('minute').all() #or_ rs = session.query(User.username).filter(or_(User.username.isnot(None),User.password == '1234')).all() print(rs)
3 多表查詢
在user_modules.py中增長一張表UserDetails表
class UserDetails(Base): __tablename__='user_details' id = Column(Integer, primary_key=True, autoincrement=True) id_card = Column(Integer,nullable=True,unique=True) lost_login = Column(DateTime) login_num = Column(Integer,default=0) user_id = Column(Integer,ForeignKey('user.id')) def __repr__(self): return '<UserDetails(id=%s,id_card=%s,last_login=%s,login_num=%s,user_id=%s)>'%( self.id, self.id_card, self.lost_login, self.login_num, self.user_id )
在query_test.py文件中導入新增長的表
from user_modules import User,UserDetails
笛卡爾鏈接:
rs =session.query(User.username,UserDetails.lost_login).filter(UserDetails.user_id==User.id).all()
去掉.all(),查看原生SQL以下:
SELECT user.id AS user_id, user.username AS user_username, user.password AS user_password,
user.create_time AS user_create_time, user._locked AS user__locked, user_details.id AS user_details_id,
user_details.id_card AS user_details_id_card, user_details.lost_login AS user_details_lost_login,
user_details.login_num AS user_details_login_num, user_details.user_id AS user_details_user_id
FROM user, user_details
WHERE user_details.user_id = user.id
inner join:內鏈接
rs = session.query(User.username,UserDetails.lost_login).\
join(UserDetails,UserDetails.user_id == User.id)
查看原生SQL以下:
SELECT user.username AS user_username, user_details.lost_login AS user_details_lost_login
FROM user INNER JOIN user_details ON user_details.user_id = user.id
###使用笛卡爾積的filter條件與使用inner join運行的結果一致。但運行的原生sql不一致。
left join:外鏈接,能夠將兩張表對調
rs = session.query(User.username,UserDetails.lost_login).\ outerjoin(UserDetails,UserDetails.user_id==User.id).all() # print(rs)
運行SQL以下:
SELECT user.username AS user_username, user_details.lost_login AS user_details_lost_login
FROM user LEFT OUTER JOIN user_details ON user_details.user_id = user.id
運行結果以下:
#兩張表對調
rs = session.query(UserDetails.lost_login,User.username).\ outerjoin(User,UserDetails.user_id==User.id).all() # print(rs)
運行SQL以下:
SELECT user_details.lost_login AS user_details_lost_login, user.username AS user_username
FROM user_details LEFT OUTER JOIN user ON user_details.user_id = user.id
運行結果以下:
union:
聯合查詢,有自動去重的功能,對應的還有 union_all
q1 = session.query(User.id) q2 = session.query(UserDetails.user_id) # print(q1.union(q2).all())
子表查詢
聲明子表
sql_0 = session.query(UserDetails.lost_login).subquery() #聲明子表
#使用 # print(session.query(User,sql_0.c.lost_login))
運行結果以下:
SELECT user.id AS user_id, user.username AS user_username, user.password AS user_password,
user.create_time AS user_create_time, user._locked AS user__locked, anon_1.lost_login AS anon_1_lost_login
FROM user, (SELECT user_details.lost_login AS lost_login
FROM user_details) AS anon_1
原生SQL查詢:
sql_1 = ''' select * from `user` ''' #查詢 row = session.execute(sql_1) #循環取值
# for i in row: # print(i)
#取值 print(row) #fetch會記錄遊標運行了上面的for之後下面就查不到數據 print(row.fetchone()) #查詢一條 print(row.fetchmany()) #在多查詢一條 print(row.fetchall()) # 差剩下的全部