Python SQLAlchemy入門教程
本文將以Mysql舉例,介紹sqlalchemy的基本用法。其中,Python版本為2.7,sqlalchemy版本為1.1.6。
一. 介紹
SQLAlchemy是Python中最有名的ORM工具。
關於ORM:
全稱Object Relational Mapping(物件關係對映)。
特點是操縱Python物件而不是SQL查詢,也就是在程式碼層面考慮的是物件,而不是SQL,體現的是一種程式化思維,這樣使得Python程式更加簡潔易讀。
具體的實現方式是將資料庫錶轉換為Python類,其中資料列作為屬性,資料庫操作作為方法。
優點:
- 簡潔易讀:將資料表抽象為物件(資料模型),更直觀易讀
- 可移植:封裝了多種資料庫引擎,面對多個數據庫,操作基本一致,程式碼易維護
- 更安全:有效避免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
)
- echo: 當設定為True時會將orm語句轉化為sql語句列印,一般debug的時候可用
- pool_size: 連線池的大小,預設為5個,設定為0時表示連線無限制
- 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的常見操作方法包括:
- flush:預提交,提交到資料庫檔案,還未寫入資料庫檔案中
- commit:提交了一個事務
- rollback:回滾
- 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 git