0%

Python sqlalchemy note — 2

前言

這次要來繼續說明 sqlalchemy 的更多操作,如果沒有看過第一篇的朋友們,可以先去看第一篇


篩選資料注意事項
在 sqlalchemy 使用 filter 篩選資料的時候
單純只使用 filter() 只會回傳 SQL 的語法回來

必需要在後面再加上其他方法,例如: all()或是 one() 來獲取我們要的資料

1
2
3
4
5
6
class_query = session.query(Student).filter(class_ == 1)
# 上述的方式會回傳的是一個 orm.query.Query的物件,印出來是 SQL 的語法
all_query = session.query(Student).filter(Student.class_ == 1).all()
# 這個方式會回傳一個 list, 裡面包含所有的結果
one_query = session.query(Student).filter(Student.class_ == 1).one()
# 回傳一個 query 裡面的 Table 的物件

然而在使用 one() 需要特別注意一件事情

只要符合條件的資料超過一筆就會引發一個 sqlalchemy.exc.MultipleResultsFound 的錯誤,在使用時一定要特別注意


多個條件篩選

只要條件越多,使用 ORM 絕對會比使用 SQL 的語法方便不少,更不用說我們還是在 python 上寫這些,要是要一個一個用 SQL 語法也不是不行,就把語法當作字串就好,再變成格式化字串填入我們要填的條件,不過這樣就會非常麻煩、難以維護而且看起來很醜。

扯遠了,假設我們今天要篩選 一班 和 二班 的學生,總不可能我們去下兩次 filter 吧,這樣只要條件一多,肯定是打 filter 打到晚上睡覺都會夢到。

為了因應這個情況,sqlalchemy 提供了 model 一個方法,就是 .in_()。

1
2
data = session.query(Student).filter(Student.class_.in_([1, 2]))
# 這樣就會去尋找 Student 裡面所有 1班、2班的學生

這個情況還算非常簡單的,我們再更複雜一點,我們不只要所有 1班 和 2班的學生,座號小於5號的,我們全部都要。

這時候我們可以這麼做

先使用一個容器儲存全部的條件,再一次解開

1
2
3
condition = [Student.class_.in_([1, 2]), Student.number < 5]
data = session.query(Student).filter(*condition).all()
# 回傳一個list,裡面包含 1.2班 "且" 座號小於五號的

如果不是用 and 的情況,要改用 or 呢?
那這時我們可以從 sqlalchemy 裡面導入 or_ 來幫助我們實現這些條件

1
2
3
4
from sqlalchemy import or_

condition = [Student.class_.in_([1, 2]), Student.number < 5]
data = session.query(Student).filter(or_(*condition)).all()

更新資料

我們可以用幾種方式更新資料,這邊簡單介紹兩種

第一種: 一個一個慢慢來

這種情況比較適合少量更新,例如:小瑪莉改名字了,改成Amy

1
2
3
student = session.query(Student).filter("name").one()  # 直接回傳物件studnet.name = "Amy"
session.commit() # 儲存資料
session.close() # 關閉

第二種情況: 一次更新所有符合條件的資料

這種情況就很適合大量的更新,例如:全班都改名成杰哥

1
2
3
student = session.query(Student).filter().update({"name": "杰哥"})
session.commit() # 儲存資料
session.close() # 關閉

這樣種方式在需要大量更新的情況下非常好用,只要把filter()的條件設定好,後面接一個update()的方法最後儲存資料就好


刪除資料

.update()相似,可以在Query這個物件後面加上.delete()這個方法

例如: 刪除所有叫做杰哥的學生

1
2
3
session.query(Student).filter(Student.name == "杰哥").delete()
session.commit()
session.close()

如果不使用Query這個物件來做刪除有沒有辦法呢?

當然有的,我們可以用session的.delete()方法,在.delete()裡面放入我們要刪除的 model物件 就可以了

例如: 刪除 2年級的學生

1
2
3
4
student = session.query(Student).filter(Student.grade == 2)
session.delete(student)
session.commit()
session.colse()

參考資料

官方文件


以上就是簡單的 sqlalchemy 介紹,如果有錯誤的部份,歡迎指正,謝謝。
如果你喜歡這篇文章,請幫我拍手
只需要註冊會員就可以囉,完全不用花費任何一毛錢就可以用來鼓裡創作者囉