Python SQLAlchemy入門教程

  • 2019 年 11 月 10 日
  • 筆記

本文將以Mysql舉例,介紹sqlalchemy的基本用法。其中,Python版本為2.7,sqlalchemy版本為1.1.6。

一. 介紹

SQLAlchemy是Python中最有名的ORM工具。

關於ORM:

全稱Object Relational Mapping(對象關係映射)。

特點是操縱Python對象而不是SQL查詢,也就是在程式碼層面考慮的是對象,而不是SQL,體現的是一種程式化思維,這樣使得Python程式更加簡潔易讀。

具體的實現方式是將資料庫錶轉換為Python類,其中數據列作為屬性,資料庫操作作為方法。

優點:

  1. 簡潔易讀:將數據表抽象為對象(數據模型),更直觀易讀
  2. 可移植:封裝了多種資料庫引擎,面對多個資料庫,操作基本一致,程式碼易維護
  3. 更安全:有效避免SQL注入

為什麼要用sqlalchemy?

雖然性能稍稍不及原生SQL,但是操作資料庫真的很方便!

二. 使用

概念和數據類型

概念

概念 對應資料庫 說明
Engine 連接 驅動引擎
Session 連接池,事務 由此開始查詢
Model 類定義
Column
Query 若干行 可以鏈式添加多個條件

常見數據類型

數據類型 資料庫數據類型 python數據類型 說明
Integer int int 整形,32位
String varchar string 字元串
Text text string 長字元串
Float float float 浮點型
Boolean tinyint bool True / False
Date date datetime.date 存儲時間年月日
DateTime datetime datetime.datetime 存儲年月日時分秒毫秒等
Time time datetime.datetime 存儲時分秒

使用步驟

創建資料庫表

1.安裝

pip install SQLalchemy

2. 創建連接

from sqlalchemy import create_engine    engine = create_engine("mysql://user:password@hostname/dbname?charset=uft8")

這行程式碼初始化創建了Engine,Engine內部維護了一個Pool(連接池)和Dialect(方言),方言來識別具體連接資料庫種類。

創建好了Engine的同時,Pool和Dialect也已經創建好了,但是此時並沒有真正與資料庫連接,等到執行具體的語句.connect()等時才會連接到資料庫。

create_engine還有其它可選的參數,比如:

engine = create_engine("mysql://user:password@hostname/dbname?charset=uft8",                         echo=True,                         pool_size=8,                         pool_recycle=60*30                         )
  1. echo: 當設置為True時會將orm語句轉化為sql語句列印,一般debug的時候可用
  2. pool_size: 連接池的大小,默認為5個,設置為0時表示連接無限制
  3. pool_recycle: 設置時間以限制資料庫多久沒連接自動斷開

3. 創建資料庫表類(模型)

前面有提到ORM的重要特點,那麼我們操作表的時候就需要通過操作對象來實現,現在我們來創建一個類,以常見的用戶表舉例:

from sqlalchemy.ext.declarative import declarative_base    Base = declarative_base()      class Users(Base):      __tablename__ = "users"        id = Column(Integer, primary_key=True)      name = Column(String(64), unique=True)      email = Column(String(64))        def __init__(self, name, email):          self.name = name          self.email = email  

declarative_base()是sqlalchemy內部封裝的一個方法,通過其構造一個基類,這個基類和它的子類,可以將Python類和資料庫表關聯映射起來。

資料庫表模型類通過__tablename__和表關聯起來,Column表示數據表的列。

4. 生成資料庫表

Base.metadata.create_all(engine)

創建表,如果存在則忽略,執行以上程式碼,就會發現在db中創建了users表。

操作數據

表創建好了就是操作數據了,常見的操作增刪改查,我們一一介紹。

session

sqlalchemy中使用session用於創建程式和資料庫之間的會話,所有對象的載入和保存都需要通過session對象 。

通過sessionmaker調用創建一個工廠,並關聯Engine以確保每個session都可以使用該Engine連接資源:

from sqlalchemy.orm import sessionmaker    # 創建session  DbSession = sessionmaker(bind=engine)  session = DbSession()

session的常見操作方法包括:

  1. flush:預提交,提交到資料庫文件,還未寫入資料庫文件中
  2. commit:提交了一個事務
  3. rollback:回滾
  4. close:關閉

舉個最簡單的例子:

add_user = Users("test", "[email protected]")  session.add(add_user)  session.commit()

session.add()將會把Model加入當前session維護的持久空間(可以從session.dirty看到)中,直到commit時提交到資料庫。

Q1:add之後如何直接返回對象的屬性?

可以在add之後執行db.session.flush(),這樣便可在session中get到對象的屬性。

Q2:如何進行批量插入,性能比較?

批量插入共有以下幾種方法,對它們的批量做了比較,分別是:

session.add_all() < bulk_save_object() < bulk_insert_mappings() < SQLAlchemy_core()

查詢是最常用的一個操作了,舉個最簡單的查詢例子:

users = session.query(Users).filter_by(id=1).all()  for item in users:      print(item.name)

通常我們通過以上查詢模式獲取數據,需要注意的是,通過session.query()我們查詢返回了一個Query對象,此時還沒有去具體的資料庫中查詢,只有當執行具體的.all(),.first()等函數時才會真的去操作資料庫。

其中,query有filter和filter_by兩個過濾方法,上述例子也可寫為:

users = session.query(Users).filter_by(Users.id == 1).all()

通常這兩個方法都會用到的,所以一定要掌握它們的區別:

filter filter_by
支援所有比較運算符,相等比較用比較用== 只能使用"=","!="和"><"
過濾用類名.屬性名 過濾用屬性名
不支援組合查詢,只能連續調用filter變相實現 參數是**kwargs,支援組合查詢
支援and,or和in等

更新數據有兩種方法,一種是使用query中的update方法:

session.query(Users).filter_by(id=1).update({'name': "Jack"})

另一種是操作對應的表模型:

users = session.query(Users).filter_by(name="Jack").first()  users.name = "test"  session.add(users)

這兩種方式呢,一般批量更新的話我會選前者,而要對查詢獲取對象屬性之後再更新的場景就需要使用後者。

和更新數據類似,刪除數據也有兩種方法,第一種:

delete_users = session.query(Users).filter(Users.name == "test").first()  if delete_users:      session.delete(delete_users)      session.commit()

第二種:

session.query(Users).filter(Users.name == "test").delete()  session.commit()

批量刪除時推薦使用第二種。

以上,就是Python sqlalchemy的基本用法。

程式碼可參照:my github