Python ORM神器之SQLAlchemy基本使用完全指南
在Python開(kāi)發(fā)中,數(shù)據(jù)庫(kù)操作是不可避免的重要環(huán)節(jié)。直接使用原生SQL雖然靈活,但容易出錯(cuò)且維護(hù)困難。SQLAlchemy作為Python中最流行的ORM(對(duì)象關(guān)系映射)框架,為我們提供了優(yōu)雅的數(shù)據(jù)庫(kù)操作方式。
一、什么是SQLAlchemy?
SQLAlchemy是一個(gè)功能強(qiáng)大的Python SQL工具包和ORM框架。它提供了完整的數(shù)據(jù)庫(kù)抽象層,讓我們可以用面向?qū)ο蟮姆绞讲僮鲾?shù)據(jù)庫(kù),而不需要直接編寫(xiě)復(fù)雜的SQL語(yǔ)句。
主要特點(diǎn):
- 數(shù)據(jù)庫(kù)無(wú)關(guān)性:支持多種數(shù)據(jù)庫(kù)(MySQL、PostgreSQL、SQLite等)
- 靈活性:既支持高層ORM,也支持底層SQL表達(dá)式
- 高性能:優(yōu)化的查詢執(zhí)行和連接池管理
- 豐富的功能:事務(wù)管理、連接池、遷移等
二、安裝SQLAlchemy
pip install sqlalchemy
三、核心概念
1. Engine(引擎)
Engine是SQLAlchemy與數(shù)據(jù)庫(kù)通信的核心組件,負(fù)責(zé)連接數(shù)據(jù)庫(kù)和執(zhí)行SQL語(yǔ)句。
from sqlalchemy import create_engine
# 創(chuàng)建引擎
engine = create_engine('sqlite:///example.db')
# MySQL示例:create_engine('mysql+pymysql://user:password@host:port/dbname')2. Session(會(huì)話)
Session是ORM與數(shù)據(jù)庫(kù)交互的主要接口,用于執(zhí)行查詢和管理事務(wù)。
from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine) session = Session()
3. Model(模型)
Model是數(shù)據(jù)庫(kù)表在Python中的對(duì)象表示,通過(guò)類來(lái)定義表結(jié)構(gòu)。
四、SQLAlchemy的基本使用
1.基本用法
通過(guò)一個(gè)完整的示例來(lái)了解SQLAlchemy的基本用法:
from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
# 創(chuàng)建基類
Base = declarative_base()
# 定義用戶模型
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(50), unique=True, nullable=False)
email = Column(String(100), unique=True, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
def __repr__(self):
return f"<User(username='{self.username}', email='{self.email}')>"
# 創(chuàng)建數(shù)據(jù)庫(kù)引擎
engine = create_engine('sqlite:///example.db', echo=True)
# 創(chuàng)建表
Base.metadata.create_all(engine)
# 創(chuàng)建會(huì)話
Session = sessionmaker(bind=engine)
session = Session()
# 創(chuàng)建用戶
new_user = User(username='alice', email='alice@example.com')
session.add(new_user)
session.commit()
# 查詢用戶
users = session.query(User).all()
for user in users:
print(user)
# 關(guān)閉會(huì)話
session.close()2.數(shù)據(jù)操作
增加數(shù)據(jù)
# 單條插入
user = User(username='bob', email='bob@example.com')
session.add(user)
session.commit()
# 批量插入
users = [
User(username='user1', email='user1@example.com'),
User(username='user2', email='user2@example.com')
]
session.add_all(users)
session.commit()查詢數(shù)據(jù)
# 基本查詢
users = session.query(User).all()
first_user = session.query(User).first()
user_by_id = session.query(User).get(1)
# 條件查詢
active_users = session.query(User).filter(User.is_active == True).all()
user_by_email = session.query(User).filter(User.email == 'alice@example.com').first()
# 復(fù)雜查詢
from sqlalchemy import and_, or_, not_
# AND條件
users = session.query(User).filter(
and_(User.is_active == True, User.username.like('%alice%'))
).all()
# OR條件
users = session.query(User).filter(
or_(User.username.like('%alice%'), User.email.like('%example%'))
).all()
# 排序和限制
recent_users = session.query(User).order_by(User.created_at.desc()).limit(10).all()
# 分頁(yè)查詢
page = 1
per_page = 20
users = session.query(User).offset((page-1)*per_page).limit(per_page).all()更新數(shù)據(jù)
# 更新單條記錄
user = session.query(User).filter(User.id == 1).first()
if user:
user.email = 'newemail@example.com'
session.commit()
# 批量更新
session.query(User).filter(User.is_active == False).update({
User.is_active: True
})
session.commit()刪除數(shù)據(jù)
# 刪除單條記錄
user = session.query(User).filter(User.id == 1).first()
if user:
session.delete(user)
session.commit()
# 批量刪除
session.query(User).filter(User.is_active == False).delete()
session.commit()五、事務(wù)管理
SQLAlchemy提供了多種事務(wù)管理方式,主要包括事務(wù)的開(kāi)啟、提交和回滾等操作。
1.事務(wù)的開(kāi)啟
在SQLAlchemy中,事務(wù)通常在執(zhí)行數(shù)據(jù)庫(kù)操作時(shí)自動(dòng)開(kāi)啟。當(dāng)使用ORM進(jìn)行數(shù)據(jù)庫(kù)操作時(shí),SQLAlchemy會(huì)自動(dòng)管理事務(wù)的生命周期。
2.事務(wù)的提交
事務(wù)提交是指將事務(wù)中的所有操作永久保存到數(shù)據(jù)庫(kù)中。在SQLAlchemy中,可以通過(guò)session.commit()方法來(lái)提交當(dāng)前事務(wù)。提交成功后,事務(wù)所做的所有更改將永久保存在數(shù)據(jù)庫(kù)中。
3.事務(wù)的回滾
當(dāng)事務(wù)執(zhí)行過(guò)程中出現(xiàn)錯(cuò)誤或者需要取消操作時(shí),可以使用回滾功能。通過(guò)session.rollback()方法,可以撤銷當(dāng)前事務(wù)中的所有操作,使數(shù)據(jù)庫(kù)恢復(fù)到事務(wù)開(kāi)始前的狀態(tài)?;貪L是保證數(shù)據(jù)一致性的重要手段。
4.完整示例
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# 創(chuàng)建數(shù)據(jù)庫(kù)連接
engine = create_engine('sqlite:///example.db', echo=True)
Base = declarative_base()
# 定義模型
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
# 創(chuàng)建表
Base.metadata.create_all(engine)
# 創(chuàng)建會(huì)話工廠
Session = sessionmaker(bind=engine)
# 創(chuàng)建會(huì)話
session = Session()
try:
# 開(kāi)始事務(wù)
user = User(username='transaction_user', email='trans@example.com')
session.add(user)
post = Post(title='Transaction Post', content='Content here')
post.author = user
session.add(post)
# 提交事務(wù)
session.commit()
print("Transaction completed successfully")
except Exception as e:
# 回滾事務(wù)
session.rollback()
print(f"Transaction failed: {e}")
finally:
session.close()六、上下文管理器
SQLAlchemy的上下文管理器提供了一種優(yōu)雅的方式來(lái)管理數(shù)據(jù)庫(kù)會(huì)話和事務(wù),通過(guò)with語(yǔ)句實(shí)現(xiàn),確保資源在使用后被正確清理和釋放,即使在發(fā)生異常的情況下也是如此。在SQLAlchemy中,上下文管理器主要用于管理會(huì)話的生命周期和事務(wù)邊界。
from contextlib import contextmanager
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# 創(chuàng)建數(shù)據(jù)庫(kù)連接
engine = create_engine('sqlite:///example.db', echo=True)
Base = declarative_base()
# 定義模型
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
# 創(chuàng)建表
Base.metadata.create_all(engine)
# 創(chuàng)建會(huì)話工廠
Session = sessionmaker(bind=engine)
# 創(chuàng)建會(huì)話
session = Session()
@contextmanager
def get_db_session():
session = Session()
try:
yield session
session.commit()
except Exception:
session.rollback()
raise
finally:
session.close()
# 使用示例
with get_db_session() as session:
user = User(username='context_user', email='context@example.com')
session.add(user)七、細(xì)節(jié)說(shuō)明
1.連接池配置
SQLAlchemy的連接池通過(guò)復(fù)用數(shù)據(jù)庫(kù)連接大幅提升性能,減少創(chuàng)建和銷毀連接的開(kāi)銷。它能智能管理資源、自動(dòng)處理失效連接,保證應(yīng)用穩(wěn)定運(yùn)行。
from sqlalchemy import create_engine
engine = create_engine(
'mysql+pymysql://user:password@localhost/dbname',
pool_size=10, # 連接池大小
max_overflow=20, # 最大溢出連接數(shù)
pool_timeout=30, # 連接超時(shí)時(shí)間
pool_recycle=3600 # 連接回收時(shí)間
)2.自動(dòng)建表
使用SQLAlchemy的declarative_base系統(tǒng)定義模型類時(shí),Base.metadata.create_all(bind=engine)方法會(huì)自動(dòng)創(chuàng)建所有還未在數(shù)據(jù)庫(kù)中創(chuàng)建的表。
但是,Base.metadata.create_all(engine) 必須在 class User(Base) 之后執(zhí)行才能成功創(chuàng)建表。
這是因?yàn)椋?/p>
- 元數(shù)據(jù)收集機(jī)制:SQLAlchemy 的 Base.metadata 是一個(gè)容器,它會(huì)自動(dòng)收集所有繼承自 Base 的模型類的表結(jié)構(gòu)信息。
- 注冊(cè)時(shí)機(jī):只有當(dāng) Python 解釋器執(zhí)行完類定義語(yǔ)句后,這個(gè)類才會(huì)被注冊(cè)到 Base.metadata 中。
- 內(nèi)部機(jī)制:當(dāng)定義 class DataRecord(Base) 時(shí),SQLAlchemy 會(huì)在 Base.metadata 中注冊(cè)這個(gè)表的定義。只有注冊(cè)之后,create_all() 才知道要?jiǎng)?chuàng)建哪些表。
3.數(shù)據(jù)庫(kù)操作方法
對(duì)于創(chuàng)建的會(huì)話db = Session(),使用db可以做很多操作。
(1)對(duì)象狀態(tài)管理操作
db.add(instance):將一個(gè)對(duì)象實(shí)例添加到當(dāng)前會(huì)話中,準(zhǔn)備插入到數(shù)據(jù)庫(kù)
db.delete(instance):標(biāo)記一個(gè)對(duì)象實(shí)例為刪除狀態(tài),準(zhǔn)備從數(shù)據(jù)庫(kù)中刪除
(2)會(huì)話控制操作
db.flush():將當(dāng)前會(huì)話中的所有掛起更改發(fā)送到數(shù)據(jù)庫(kù),但不提交事務(wù)
db.commit():提交當(dāng)前事務(wù),將所有更改永久保存到數(shù)據(jù)庫(kù)
db.rollback():回滾當(dāng)前事務(wù),撤銷所有未提交的更改
db.close():關(guān)閉會(huì)話,清理資源
(3)查詢操作
db.query(Model):創(chuàng)建一個(gè)查詢對(duì)象
db.execute(statement):執(zhí)行原生SQL語(yǔ)句
(4)其他會(huì)話方法
db.merge(instance):將實(shí)例的狀態(tài)合并到當(dāng)前會(huì)話中,如果實(shí)例已在會(huì)話中則更新,否則添加
db.refresh(instance):從數(shù)據(jù)庫(kù)重新加載對(duì)象的狀態(tài)
4.db.add() 和 db.commit() 的區(qū)別
(1)db.add()用于將對(duì)象添加到當(dāng)前會(huì)話中,使SQLAlchemy開(kāi)始跟蹤這個(gè)對(duì)象的狀態(tài)變化。當(dāng)調(diào)用session.add()時(shí),對(duì)象會(huì)被放入會(huì)話的待處理隊(duì)列中,但此時(shí)數(shù)據(jù)并不會(huì)立即寫(xiě)入數(shù)據(jù)庫(kù),而是保持在內(nèi)存中等待后續(xù)操作。
(2)db.commit()則是將當(dāng)前會(huì)話中的所有變更(包括添加、修改、刪除等操作)真正提交到數(shù)據(jù)庫(kù)的過(guò)程。執(zhí)行commit()時(shí),SQLAlchemy會(huì)生成相應(yīng)的SQL語(yǔ)句并執(zhí)行,將內(nèi)存中的變更持久化到數(shù)據(jù)庫(kù)中,同時(shí)結(jié)束當(dāng)前事務(wù)。
到此這篇關(guān)于Python ORM神器之SQLAlchemy基本使用完全指南的文章就介紹到這了,更多相關(guān)Python SQLAlchemy使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python?ORM數(shù)據(jù)庫(kù)框架Sqlalchemy的使用教程詳解
- Python?ORM框架之SQLAlchemy?的基礎(chǔ)用法
- Python3+SQLAlchemy+Sqlite3實(shí)現(xiàn)ORM教程
- Python流行ORM框架sqlalchemy安裝與使用教程
- Python的ORM框架中SQLAlchemy庫(kù)的查詢操作的教程
- Python ORM框架SQLAlchemy學(xué)習(xí)筆記之?dāng)?shù)據(jù)添加和事務(wù)回滾介紹
- Python ORM框架SQLAlchemy學(xué)習(xí)筆記之映射類使用實(shí)例和Session會(huì)話介紹
- Python ORM框架SQLAlchemy學(xué)習(xí)筆記之關(guān)系映射實(shí)例
- Python的ORM框架SQLAlchemy入門教程
相關(guān)文章
Python超越函數(shù)積分運(yùn)算以及繪圖實(shí)現(xiàn)代碼
今天小編就為大家分享一篇Python超越函數(shù)積分運(yùn)算以及繪圖實(shí)現(xiàn)代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
Python入門之使用pandas分析excel數(shù)據(jù)
這篇文章主要給大家介紹了關(guān)于Python入門學(xué)習(xí)之使用pandas分析excel數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
教你怎么用PyCharm為同一服務(wù)器配置多個(gè)python解釋器
當(dāng)我們?cè)诜?wù)器上創(chuàng)建了多個(gè)虛擬環(huán)境時(shí),也可以在 PyCharm 中配置這些虛擬環(huán)境,方便不同的項(xiàng)目使用不同的環(huán)境,然而按照網(wǎng)上教程添加多個(gè)python解釋器后,PyCharm會(huì)自動(dòng)幫我們創(chuàng)建多個(gè)重復(fù)的服務(wù)器,本文主要給出該問(wèn)題的解決方法,同時(shí)也對(duì)添加解釋器做一個(gè)詳細(xì)的講解2021-05-05
運(yùn)用TensorFlow進(jìn)行簡(jiǎn)單實(shí)現(xiàn)線性回歸、梯度下降示例
這篇文章主要介紹了運(yùn)用TensorFlow進(jìn)行簡(jiǎn)單實(shí)現(xiàn)線性回歸、梯度下降示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
django.db.utils.ProgrammingError: (1146, u“Table‘’ doesn’t e
這篇文章主要給大家介紹了關(guān)于執(zhí)行python manage.py migrate時(shí)報(bào)錯(cuò):django.db.utils.ProgrammingError: (1146, "Table 'test.model_student' doesn't exist" )問(wèn)題的解決方法,文中將解決的方法介紹的非常詳細(xì),需要的朋友可以參考下2018-07-07
Python?Pygame實(shí)戰(zhàn)之五款童年經(jīng)典游戲合集
本文為大家總結(jié)了五款利用Python+Pygame實(shí)現(xiàn)的童年經(jīng)典游戲:推箱子、滑雪、八分音符醬、保衛(wèi)蘿卜和飛機(jī)大戰(zhàn),快跟隨小編一起學(xué)習(xí)一下2022-04-04
Python操作Sqlite正確實(shí)現(xiàn)方法解析
我們今天將會(huì)在這篇文章中分步驟為大家詳細(xì)介紹一下有關(guān)Python操作Sqlite的相關(guān)應(yīng)用方式,希望大家可以從中獲得一些幫助2020-02-02
利用Python和C語(yǔ)言分別實(shí)現(xiàn)哈夫曼編碼
這篇文章主要為大家詳細(xì)介紹了如何利用Python和C語(yǔ)言分別實(shí)現(xiàn)哈夫曼編碼,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-07-07
一文帶你玩轉(zhuǎn)Python必備的幾種數(shù)據(jù)格式
在Python開(kāi)發(fā)中,數(shù)據(jù)格式的選擇直接影響著程序的性能和可維護(hù)性,本文將詳細(xì)介紹Python開(kāi)發(fā)中最常用的幾種數(shù)據(jù)格式,希望可以幫助大家選擇最合適的數(shù)據(jù)表示方式2025-06-06
Python中的鴨子類型實(shí)際應(yīng)用之理解動(dòng)態(tài)類型的力量
鴨子類型是Python動(dòng)態(tài)類型系統(tǒng)的重要特性之一,它通過(guò)關(guān)注對(duì)象的行為而非類型,提供了極大的靈活性和簡(jiǎn)潔性,本文介紹Python中的鴨子類型:理解動(dòng)態(tài)類型的力量,感興趣的朋友跟隨小編一起看看吧2025-10-10

