Tornado-0九、SQLalchemy的查詢

1.帶條件的查詢

查詢是最經常使用的,對於各類查詢咱們必需要十分清楚,首先是帶條件的查詢sql

#查詢特定字段
rows = session.query(User).filter_by(username='budong').all()
print(rows)  # 返回User對象
rows1 = session.query(User).filter(User.username=='budong').all()
print(rows1)  # 返回User對象
rows2 = session.query(User.username).filter(User.

username=='budong').all() # 返回的是值session

print(rows2)
rows3 = session.query(User.username).filter(User.username=='budong')
print(rows3)  # 返回的是值

filter_by和filter都是過濾條件,只是用法有區別filter_by裏面不能用!=還有> < 等等,全部filter用得更多,filter_by只能用=。函數

前兩個查詢的是User,因此返回結果也是一個對象,可是rows2查詢的是屬性值,因此返回的是屬性值。fetch

rows3能夠看到SQLAlchemy轉成的SQL語句,SQLAlchemy最後都是會轉成SQL語句,經過這個方法能夠查看原生SQL,甚至有些時候咱們須要把SQLAlchemy轉成的SQL交給DBA審查,合適的才能使用。code

查詢要知道查詢結果的返回怎樣的數據orm

#基本查詢
print( session.query(User).filter(User.username=='budong').all() )
print( session.query(User).filter(User.username=='budong').first())
print( session.query(User).filter(User.username=='budong').one())
print( session.query(User).get(2))

上面三條記錄,第一個查出全部符合條件的記錄,第二個查出全部符合記錄的第一條記錄,第三個返回一個對象,若是結果有多條就會報錯,第四個經過主鍵獲取記錄對象

除此以外,咱們偶爾也會須要限制返回的結果數量sqlalchemy

#限制查詢返回結果
print( session.query(User).filter(User.username!='budong').limit(2).all())
# 最多返回兩條記錄 
print( session.query(User).filter(User.username!='budong').offset(2).all())
# 從第3條記錄開始返回
print( session.query(User).filter(User.username!='budong').slice(2,3).all())
#  截取第2到第3條
#能夠排序以後再進行限制
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是降序。ip

還有其餘的帶條件查詢

#不等於
print( session.query(User).filter(User.username!='budong').all() )
#模糊匹配 like
print( session.query(User).filter(User.username.like('budong')).all() )
print( session.query(User).filter(User.username.notlike('budong')).all() )
#成員屬於  in_
print( session.query(User).filter(User.username.in_(['budong','tuple'])).all() )
#成員不屬於  notin_
print( session.query(User).filter(User.username.notin_(['budong','tuple'])).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=='budong',User.password=='qwe123')).all() )
print( session.query(User).filter(and_(User.username=='budong',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() )  # 查出全部id>1的信息
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)
相關文章
相關標籤/搜索