SQLAlchemy 是 Python 最知名的 ORM(Object-Relational Mapping)框架,將關聯式資料表映射為 Python 類別,讓資料庫操作更直觀、安全。本文從安裝、模型定義、CRUD 操作到關聯關係完整說明。
傳統 DB-API 回傳元組列表:
[('1', 'Michael'), ('2', 'Bob'), ('3', 'Adam')]
ORM 映射為物件:
class User(object):
def __init__(self, id, name):
self.id = id
self.name = name
[User('1', 'Michael'), User('2', 'Bob'), User('3', 'Adam')]
ORM 框架自動處理「資料列 ⇄ 物件」雙向轉換。
# 安裝
$ easy_install sqlalchemy
# 或
$ pip install sqlalchemy
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# 基類
Base = declarative_base()
# 定義模型
class User(Base):
__tablename__ = 'user'
id = Column(String(20), primary_key=True)
name = Column(String(20))
# 資料庫連線
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
DBSession = sessionmaker(bind=engine)
連線字串格式:dialect+driver://user:pass@host:port/dbname
session = DBSession()
new_user = User(id='5', name='Bob')
session.add(new_user)
session.commit()
session.close()
session = DBSession()
user = session.query(User).filter(User.id=='5').one()
print('type:', type(user))
print('name:', user.name)
session.close()
輸出:
type:
name: Bob
class User(Base):
__tablename__ = 'user'
id = Column(String(20), primary_key=True)
name = Column(String(20))
books = relationship('Book') # 一對多
class Book(Base):
__tablename__ = 'book'
id = Column(String(20), primary_key=True)
name = Column(String(20))
user_id = Column(String(20), ForeignKey('user.id')) # 外鍵
查詢 user.books 即獲取該使用者所有書籍物件列表。
# 使用 context manager 確保關閉
from contextlib import contextmanager
@contextmanager
def session_scope():
session = DBSession()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
# 使用
with session_scope() as session:
user = session.query(User).filter_by(id='5').first()
user.name = 'Updated'
| 方法 | 說明 |
|---|---|
| query(Model) | 建立查詢 |
| filter(condition) | WHERE 條件 |
| filter_by(**kwargs) | 簡單等值過濾 |
| one() | 單一結果,無/多筆拋異常 |
| first() | 第一筆或 None |
| all() | 所有結果列表 |
| count() | 統計筆數 |
| order_by(col) | 排序 |
| limit(n), offset(n) | 分頁 |