Tornado 數(shù)據(jù)庫_ORM_SQLAlchemy_查詢操作

上節(jié)課使用query從數(shù)據(jù)庫中查詢到了結(jié)果,但是query返回的對象是直接可用的嗎?

query:
from connect import session
from user_module import User

result = session.query(User)

print(result,type(result)) #返回是一個(gè)query對象,打印出來可以看到轉(zhuǎn)化過后的SQL
image.png

根據(jù)以上返回是一個(gè)query對象施流,打印出來可以看到轉(zhuǎn)化過后的SQL。

filter:
from connect import session
from user_module import User

result = session.query(User).filter(User.username=='cainiao')

print(result,type(result)) #返回是一個(gè)query對象鄙信,打印出來可以看到轉(zhuǎn)化過后的SQL
image.png

根據(jù)以上返回是一個(gè)query對象瞪醋,打印出來可以看到轉(zhuǎn)化過后的SQL。

all:

all 是返回所有符合條件的數(shù)據(jù)装诡。

result = session.query(User).filter(User.username=='cainiao').all()
print(result,type(result)) ##返回的是一個(gè)list,列表里面是一個(gè)類
image.png

根據(jù)以上返回的是一個(gè)list,列表里面是一個(gè)類银受。

first:

first 是返回所有符合條件數(shù)據(jù)的第一條數(shù)據(jù)践盼。

result = session.query(User).filter(User.username=='cainiao').first()
print(result,type(result)) #返回類的實(shí)例化

根據(jù)以上返回的是類的實(shí)例化

索引
result1 = session.query(User)
print(result1,type(result1)) #返回是一個(gè)query對象,打印出來可以看到轉(zhuǎn)化過后的SQL

result2 = session.query(User)[0]
print(result2,type(result2))    #返回類的實(shí)例化
result3 = session.query(User).all()[0]
print(result3,type(result3))  #返回類的實(shí)例化

result4= session.query(User).first()
print(result4,type(result4))  #返回類的實(shí)例化

image.png

索引為0的值蚓土,類似于first宏侍,但是不等同于,空列表用這個(gè)會報(bào)錯(cuò)J衿帷谅河!

取值

對于類的實(shí)例化可以用.getattr來獲取字段值

#對于類的實(shí)例化可以用.來獲取字段值
print(result2.username)
print(result3.username)
print(result4.username)

#也可以用getattr方法
print(getattr(result2,'username'))
print(getattr(result2,'username'))
print(getattr(result2,'username'))
image.png

在query里面指定了某個(gè)屬性值,返回是直接查詢User.username的值确丢,所以就返回了包括元組的列表

result = session.query(User.username).all()
print(result,type(result))  #在query里面指定了某個(gè)屬性值绷耍,返回是直接查詢User.username的值,所以就返回了包括元組的列表

print(session.query(User.username).first()) #返回元祖
image.png

過濾函數(shù)

filter是一個(gè)過濾函數(shù)鲜侥,過濾條件都可以書寫在次函數(shù)中褂始,不同的條件之間用逗號隔開。filter_by 也是一個(gè)過濾函數(shù)描函,但是功能要弱一些崎苗。

result1 = session.query(User).filter(User.username=='cainiao',User.password=='1').all()
print(result1)
result2 = session.query(User).filter_by(username='cainiao').all()
print(result2)

區(qū)別:
二者都是 過濾函數(shù),但是使用有如下差別:

  1. filter 中需要添加 類對象舀寓,filter_by不需要胆数。
  2. filter_by 中只能添加等于的條件,不能添加 不等于互墓、大于小于等條件必尼,filter沒有這個(gè)限制。

模糊查詢

like和notlike

like 是模糊查詢篡撵,和數(shù)據(jù)庫中的 like 用法一樣判莉,notlike 和 like 作用相反。

#like 是模糊查詢育谬,和數(shù)據(jù)庫中的 like 用法一樣券盅,notlike 和 like 作用相反。
result1 = session.query(User.id).filter(User.username.like('cainiao%')).all()
result2 = session.query(User.id).filter(User.username.notlike('cainiao%')).all()
print(result1,result2)
image.png
in_和notin_

in_ 和 notin_ 是范圍查找

result1 = session.query(User.id).filter(User.username.in_(['cainiao', 'cainiao1'])).all()
result2 = session.query(User.id).filter(User.username.notin_(['cainiao2', 'cainiao3'])).all()
print(result1,result2)
image.png
is_和isnot

is_ 和 isnot精確查找

#is_  和 isnot精確查找
result1 = session.query(User.id).filter(User.username.is_(None)).all()
result2 = session.query(User.id).filter(User.username.isnot(None)).all()
print(result1,result2)

#判斷為空還可以使用:
result3 = session.query(User.id).filter(User.username==None).all()
print(result3)
image.png

查詢結(jié)果

#先用 all 查看所有的數(shù)據(jù)
result1 = session.query(User.username).filter(User.username!='cainiao%').all()
#查看前2條數(shù)據(jù)
result2 = session.query(User.username).filter(User.username!='cainiao').limit(2).all()
#偏移一條記錄膛檀,偏移1個(gè)锰镀,前面1個(gè)數(shù)據(jù)不看,從第2個(gè)數(shù)據(jù)開始查詢
result3 = session.query(User.username).filter(User.username!='cainiao').offset(1).all()

#slice   對查詢出來的數(shù)據(jù)進(jìn)行切片取值,#切片宿刮,索引0到1的數(shù)據(jù)
result4 = session.query(User.username).filter(User.username!='cainiao').slice(0,2).all()

#one  查詢一條數(shù)據(jù)互站,如果存在多條則報(bào)錯(cuò),可以用來測試是否只有一條
result5 = session.query(User.username).filter(User.username!='cainiao').one()

排序


#導(dǎo)入模塊
from sqlalchemy import desc,asc

#默認(rèn)正序私蕾,asc也是正序
result1 = session.query(User.id).filter(User.username=='cainiao').order_by(User.id).all()
result2 = session.query(User.id).filter(User.username=='cainiao').order_by(asc(User.id)).all()
#desc 是倒序排序
result3 = session.query(User.id).filter(User.username=='cainiao').order_by(desc(User.id)).all()
#order_by  和 limit 一起使用的時(shí)候
result4 = session.query(User.id).filter(User.username=='cainiao').order_by(User.id).limit(2).all()
print(result1,type(result1))
print(result2,type(result2))
print(result3,type(result3))
print(result4,type(result4))
image.png

默認(rèn)為正序僵缺,asc。desc為倒序踩叭。

函數(shù)

#導(dǎo)入
from sqlalchemy import func,extract

result1 = session.query(func.count(User.id)).all() #select count(id) from users
#用到group_by 磕潮,查詢的列是分組的列翠胰,或者某個(gè)列的聚合函數(shù)
result2 = session.query(User.username).group_by(User.username).all() #select username from users group by username
result3 = session.query(User.username,func.count(User.id)).group_by(User.username).all() #select username,count(id) from users group by username
result4 = session.query(User.username).group_by(User.username).having(func.count(User.id)<4).all()

#group_by 和 order_by 一樣,是可以直接使用的自脯,不需要導(dǎo)入,having 也可以直接使用之景,使用方法也和 SQL 中使用類似。

print(result1,type(result1))
print(result2,type(result2))
print(result3,type(result3))
print(result4,type(result4))
image.png

用到group_by 膏潮,查詢的列是分組的列锻狗,或者某個(gè)列的聚合函數(shù)。

聚合函數(shù)

#sum 求和

result1 = session.query(func.sum(User.id)).filter(User.username=='cainiao').all()
#max 求最大值

result2 = session.query(func.max(User.id)).filter(User.username=='cainiao').all()

#min 求最小值
result3 = session.query(func.min(User.id)).filter(User.username=='cainiao').all()

print(result1)
print(result2)
print(result3)
image.png

常用聚合函數(shù):count 焕参、 sum avg 轻纪、 max 、 min

extract
#extract 提取對象中的數(shù)據(jù)叠纷,這里提取分鐘刻帚,并把提取出來的結(jié)果用 label 命名別名,之后就可以使用 group_by 來分組

session.query(extract('minute',User.creatime).label('minute'), func.count(User.id)).group_by('minute').all()

選擇條件

from sqlalchemy import or_
result1 = session.query(User.id).filter(User.username=='cainiao').all()
result2 = session.query(User.id).filter(User.id==3).all()
result3 = session.query(User.id).filter(or_(User.username=='cainiao',User.id==3)).all()

print(result1)
print(result2)
print(result3)
image.png

多表查詢

新建module
class UserDetails(Base):
    __tablename__ = 'user_details'
    id = Column(Integer,primary_key=True,autoincrement=True)
    id_card = Column(Integer,nullable=True,unique=True)
    last_login =Column(DateTime)
    login_num = Column(Integer,default=0)
    user_id = Column(Integer,ForeignKey('users.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.last_login,self.login_num,
            self.user_id)

cross join笛卡爾積

cross join交叉連接涩嚣。交叉連接返回左表中的所有行崇众,左表中的每一行與右表中的所有行組合。交叉連接也稱作笛卡爾積航厚。

from user_module import UserDetails
result1 = session.query(UserDetails,User) #cross join 第一張表每一項(xiàng)與第二張表交叉連接
print(result1,type(result1))
image.png

inner join內(nèi)連接

內(nèi)連接inner join顷歌,內(nèi)連接,只查匹配行阶淘。

result2 = session.query(User.username, UserDetails.last_login).join(UserDetails,UserDetails.id==User.id) #內(nèi)連接
print(result2)
image.png

外連接

外連接衙吩,至少有一方保留全集,沒有匹配行用NULL代替溪窒。外連接分為三種:左外連接坤塞,右外連接,全外連接澈蚌。對應(yīng)SQL:LEFT/RIGHT/FULL OUTER JOIN摹芙。通常我們省略outer 這個(gè)關(guān)鍵字。寫成:LEFT/RIGHT/FULL JOIN宛瞄。

  1. 左外連接:左表不加限制浮禾,保留左表的數(shù)據(jù),匹配右表份汗,右表沒有匹配2到的行中的列顯示為null盈电。
  2. 右外連接:右表不加限制,保留右表的數(shù)據(jù)杯活。匹配左表匆帚,左表沒有匹配到的行中列顯示為null。
  3. 完全外連接:左右表都不加限制旁钧。即右外連接的結(jié)果為:左右表匹配的數(shù)據(jù)+左表沒有匹配到的數(shù)據(jù)+右表沒有匹配到的數(shù)據(jù)吸重。
#左連接 left join結(jié)果集保留左表的所有行互拾,但只包含第二個(gè)表與第一表匹配的行。第二個(gè)表相應(yīng)的空行被放入NULL值嚎幸。
result3 = session.query(User.username, UserDetails.last_login).outerjoin(UserDetails,UserDetails.id==User.id) #左連接
print(result3,type(result3))

#sqlalchemy沒有right join颜矿,右連接將表反過來寫即可。
result4 = session.query(UserDetails.last_login,User.username).outerjoin(User,User.id==UserDetails.id)

print(result4,type(result4))
image.png

union

union 是聯(lián)合查詢嫉晶,有自動去重的功能骑疆,對應(yīng)的還有 union_all,UNION 操作符用于合并兩個(gè)或多個(gè) SELECT 語句的結(jié)果集。

#union 是聯(lián)合查詢替废,有自動去重的功能封断,對應(yīng)的還有 union_all,UNION 操作符用于合并兩個(gè)或多個(gè) SELECT 語句的結(jié)果集。
q1 = session.query(User.id)
q2 = session.query(UserDetails.id)
result1 = q1.union(q2)
result2 = q1.union_all(q2)

print(q1.all())
print(q2.all())
print(result1.all(),type(result1))
print(result2.all(),type(result2))
image.png

union:聯(lián)合的意思舶担,即把兩次或多次查詢結(jié)果合并起來坡疼。
要求:兩次查詢的列數(shù)必須一致
推薦:列的類型可以不一樣,但推薦查詢的每一列衣陶,想對應(yīng)的類型以一樣
可以來自多張表的數(shù)據(jù):多次sql語句取出的列名可以不一致柄瑰,此時(shí)以第一個(gè)sql語句的列名為準(zhǔn)。
如果不同的語句中取出的行剪况,有完全相同(這里表示的是每個(gè)列的值都相同)教沾,那么union會將相同的行合并,最終只保留一行译断。也可以這樣理解授翻,union會去掉重復(fù)的行。
如果不想去掉重復(fù)的行孙咪,可以使用union all堪唐。

子表查詢

是指出現(xiàn)在其他SQL語句內(nèi)的SELECT字句。嵌套在查詢內(nèi)部翎蹈,且必須始終出現(xiàn)在圓括號內(nèi)淮菠。子查詢里面只能查詢一個(gè)東西,不能查詢多個(gè)荤堪,因?yàn)橥饷娼邮盏闹荒芙邮找粋€(gè)合陵。

#子表查詢
#subquery聲明子表
sql_0 =session.query(UserDetails.last_login).subquery()

#使用
result2 = session.query(User,sql_0.c.last_login)
print(result2)
image.png

原生sql查詢


sql = "select * from users"
row = session.execute(sql)

print(row.fetchall()) #注意類似游標(biāo)指針一次查詢指針會指到本次查詢的末尾處
print(row.fetchone())
print(row.fetchmany())

#循環(huán)獲取
for i in row:
    print(i)
image.png
pycharm快速添加數(shù)據(jù)

點(diǎn)擊右邊Database:


image.png

點(diǎn)擊添加:


image.png

設(shè)置配置信息:
image.png

測試連接成功,點(diǎn)擊保存:


image.png

點(diǎn)擊右邊就可以在左邊進(jìn)行相關(guān)操作了
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末澄阳,一起剝皮案震驚了整個(gè)濱河市拥知,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碎赢,老刑警劉巖低剔,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異揩抡,居然都是意外死亡户侥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門峦嗤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕊唐,“玉大人,你說我怎么就攤上這事烁设√胬妫” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵装黑,是天一觀的道長副瀑。 經(jīng)常有香客問我,道長恋谭,這世上最難降的妖魔是什么糠睡? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮疚颊,結(jié)果婚禮上狈孔,老公的妹妹穿的比我還像新娘。我一直安慰自己材义,他們只是感情好均抽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著其掂,像睡著了一般油挥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上款熬,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天深寥,我揣著相機(jī)與錄音,去河邊找鬼贤牛。 笑死翩迈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的盔夜。 我是一名探鬼主播负饲,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喂链!你這毒婦竟也來了返十?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤椭微,失蹤者是張志新(化名)和其女友劉穎洞坑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝇率,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迟杂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年刽沾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片排拷。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侧漓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出监氢,到底是詐尸還是另有隱情布蔗,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布浪腐,位于F島的核電站纵揍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏议街。R本人自食惡果不足惜泽谨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望特漩。 院中可真熱鬧隔盛,春花似錦、人聲如沸拾稳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽访得。三九已至龙亲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悍抑,已是汗流浹背鳄炉。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搜骡,地道東北人拂盯。 一個(gè)月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像记靡,于是被迫代替她去往敵國和親谈竿。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容