Python中SQLAlchemy庫的使用方法分析
1. 基本知識
一、ORM (對象關系映射):
- SQLAlchemy 是Python SQL工具包和對象關系映射器(ORM),允許Python開發(fā)者在應用程序中使用SQL來交互,而無需處理數(shù)據(jù)庫的具體細節(jié)
- 提供一個高層的抽象層,允許開發(fā)者通過Python類和對象來表示數(shù)據(jù)庫中的表和行,從而使得數(shù)據(jù)庫操作更加方便和靈活
二、核心(Core):
SQLAlchemy 的核心部分提供了一組工具來執(zhí)行SQL操作,包括創(chuàng)建和執(zhí)行SQL語句
、連接池管理
、事務管理
等。開發(fā)者可以使用核心部分來執(zhí)行一些高級的數(shù)據(jù)庫操作,如自定義SQL語句
、連接到數(shù)據(jù)庫
等。
三、優(yōu)點:
靈活性
:
多種不同的方式來與數(shù)據(jù)庫交互,包括使用核心部分執(zhí)行原始SQL語句、使用ORM進行對象關系映射、以及使用表達式語言構建SQL查詢等
功能豐富
:
許多功能豐富的工具和API,滿足各種不同的數(shù)據(jù)庫操作需求
ORM支持
:
SQLAlchemy 的ORM工具允許開發(fā)者使用Python類來代表數(shù)據(jù)庫中的表和行,從而使得數(shù)據(jù)庫操作更加Pythonic和易于理解
ORM工具提供了一種高級的抽象,隱藏了底層數(shù)據(jù)庫操作的細節(jié),使得開發(fā)者可以更專注于業(yè)務邏輯的實現(xiàn)
跨數(shù)據(jù)庫支持
:
支持多種不同的數(shù)據(jù)庫后端,包括MySQL、PostgreSQL、SQLite等
活躍的社區(qū)
:
SQLAlchemy 有一個活躍的社區(qū),提供了大量的文檔、教程和示例代碼,使得開發(fā)者可以更容易地學習和使用這個工具包
四、缺點:性能開銷
盡管SQLAlchemy提供了許多便利的功能,但有時候這些功能可能會帶來一定的性能開銷。特別是在處理大量數(shù)據(jù)或需要高性能的場景下,可能需要仔細優(yōu)化代碼以減少性能損失
五、與其他工具比較:
與其他ORM工具的比較:
Django ORM | Peewee | SQLObject |
---|---|---|
與Django ORM相比,SQLAlchemy提供了更多的靈活性和功能,尤其是在處理復雜數(shù)據(jù)庫操作和跨數(shù)據(jù)庫支持方面 但Django ORM更容易上手,并且與Django框架無縫集成,適合快速開發(fā)和小型項目 | Peewee 是另一個輕量級的Python ORM工具,相比于SQLAlchemy,它的學習曲線更為平緩,適合于簡單的數(shù)據(jù)庫操作和小型項目 但Peewee的功能相對較少,不如SQLAlchemy靈活 | SQLObject 是另一個Python ORM庫,它的設計更加接近于Active Record模式,與SQLAlchemy的Data Mapper模式有所不同 但SQLObject的學習曲線較陡,且功能相對較少,通常適用于簡單的數(shù)據(jù)庫操作 |
2. 基本API
- 安裝庫:
pip install SQLAlchemy
- 驗證是否安裝成功:
python -c "import sqlalchemy; print(sqlalchemy.__version__)"
或者pip show sqlalchemy
為了讓大家更快上手,先學習下下面這個實戰(zhàn)項目:
from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base # 創(chuàng)建引擎 engine = create_engine('mysql+pymysql://root:root@127.0.0.1:3306/easy-admin') # 創(chuàng)建Session Session = sessionmaker(bind=engine) session = Session() # 定義映射類 Base = declarative_base() class User(Base): __tablename__ = 'manong' id = Column(Integer, primary_key=True) name = Column(String(255)) # 在這里指定了 name 列的長度為 255 age = Column(Integer) # 創(chuàng)建表 Base.metadata.create_all(engine) # 插入數(shù)據(jù) new_user = User(name='yanjiuseng', age=25) session.add(new_user) session.commit() # 查詢數(shù)據(jù) query = session.query(User).filter(User.age > 18) result = query.all() for user in result: print(user.name, user.age)
最終截圖如下:
通過看完整個代碼邏輯,帶著一些小疑問,深入探討下這些API的使用方式
2.1 create_engine(創(chuàng)建引擎)
create_engine
函數(shù)用于創(chuàng)建一個與數(shù)據(jù)庫的連接引擎,該引擎可以執(zhí)行SQL操作
from sqlalchemy import create_engine engine = create_engine('mysql+pymysql://username:password@host:port/database')
針對里頭的參數(shù)解釋如下:
mysql
:指定數(shù)據(jù)庫類型,這里是 MySQL 數(shù)據(jù)庫username
:數(shù)據(jù)庫用戶名password
:數(shù)據(jù)庫密碼host
:數(shù)據(jù)庫主機名或 IP 地址port
:數(shù)據(jù)庫端口號,默認是 MySQL 的端口號 3306database
:要連接的數(shù)據(jù)庫名稱
MySQL 數(shù)據(jù)庫用戶名是 user1,密碼是 pass123,主機名是 localhost,端口號是 3306,要連接的數(shù)據(jù)庫名稱是 my_database,那么連接字符串就應該是:
'mysql://user1:pass123@localhost:3306/my_database'
對于數(shù)據(jù)庫類型常用的:mysql+pymysql
,主要區(qū)別在于其使用的數(shù)據(jù)庫驅動程序不同。
mysql+pymysql
:(更簡單地安裝和使用,可以選擇使用 pymysql)
指定使用 PyMySQL 作為連接 MySQL 數(shù)據(jù)庫的驅動程序,PyMySQL 是一個純 Python 實現(xiàn)的 MySQL 客戶端庫,兼容 Python 數(shù)據(jù)庫 API 規(guī)范 2.0,可以在 Python 中直接使用mysql
:(對性能要求比較高,可以選擇使用 mysql 并配合 MySQLdb 或者 mysqlclient)
沒有指定具體的數(shù)據(jù)庫驅動程序,使用默認的 MySQL 客戶端庫,一般情況下會使用 MySQLdb 或者 mysqlclient
再額外補充其他的URL格式:
# MySQL-Python: mysql+mysqldb://<user>:<password>@<host>:<port>/<dbname> # pymysql: mysql+pymysql://<username>:<password>@<host>:<port>/<dbname>?<options> # MySQL-Connector: mysql+mysqlconnector://<user>:<password>@<host>:<port>/<dbname> # cx_Oracle: oracle+cx_oracle://<user>:<password>@<host>:<port>/<dbname>?key=value&key=value...
2.2 sessionmaker(創(chuàng)建session)
用于創(chuàng)建一個 Session 類,該類用于執(zhí)行 ORM(對象關系映射)操作
主要作用是創(chuàng)建一個會話工廠,通過工廠可以創(chuàng)建數(shù)據(jù)庫會話對象,用于在代碼中執(zhí)行數(shù)據(jù)庫操作
# 創(chuàng)建Session Session = sessionmaker(bind=engine) session = Session()
其中sessionmaker的參數(shù)如下:
bind
:要綁定到的數(shù)據(jù)庫引擎,通常是一個 create_engine 函數(shù)返回的 Engine 對象class_
:可選參數(shù),指定要創(chuàng)建的會話類,默認為 Session 類autocommit
:是否自動提交事務,默認為 Falseautoflush
:是否自動刷新會話,默認為 Trueexpire_on_commit
:在提交事務時是否自動使對象過期,默認為 Trueinfo
:一個字典,用于指定會話的其他配置信息
具體示例如下:
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 創(chuàng)建引擎 engine = create_engine('sqlite:///example.db') # 創(chuàng)建會話工廠 Session = sessionmaker(bind=engine, autocommit=False, autoflush=True) # 創(chuàng)建會話對象 session = Session()
需要注意的點如下:
- 在使用會話對象執(zhí)行數(shù)據(jù)庫操作后,一般需要調用
commit
方法提交事務,或者調用rollback
方法回滾事務。 - 在會話對象的作用域結束時,通常需要調用
close
方法關閉會話,釋放數(shù)據(jù)庫連接資源。
2.3 declarative_base(定義映射類)
使用 ORM 進行數(shù)據(jù)庫操作的核心部分之一,涉及到將數(shù)據(jù)庫中的表映射到 Python 中的類,以及定義類屬性來表示表的列
一、映射類的定義:
通過創(chuàng)建Python 類來表示數(shù)據(jù)庫中的表
該類通常繼承自 SQLAlchemy 的 Base 類,而 Base 類是使用 declarative_base()
函數(shù)創(chuàng)建的
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base()
二、表的映射:
在映射類中定義 __tablename__
屬性,指定該類所映射的數(shù)據(jù)庫表的名稱
class User(Base): __tablename__ = 'users'
三、列的映射:
在映射類中定義類屬性,來表示表中的列
每個類屬性通常都會被定義為 Column
對象,并指定其數(shù)據(jù)類型以及其他屬性
from sqlalchemy import Column, Integer, String class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String(255)) age = Column(Integer)
對應的屬性如下:
屬性的含義:
Column
:表示一個數(shù)據(jù)庫表的列Integer
、String
等數(shù)據(jù)類型:表示列的數(shù)據(jù)類型primary_key=True
:指定該列為主鍵
其他參數(shù):例如長度、唯一性等,用于進一步定義列的屬性
2.4 SQL與ORM差異
一、基于 SQL 的查詢:
特點:
原始的 SQL 查詢語句,手動編寫 SQL 語句來執(zhí)行數(shù)據(jù)庫操作。于執(zhí)行復雜的查詢、跨表查詢或性能要求較高的場景
示例代碼:
from sqlalchemy import create_engine, text # 創(chuàng)建引擎 engine = create_engine('mysql+pymysql://root:root@127.0.0.1:3306/easy-admin') # 執(zhí)行 SQL 查詢 with engine.connect() as connection: result = connection.execute(text("SELECT * FROM manong WHERE age > :age"), {'age': 18}) for row in result: print(row)
截圖如下:
二、基于ORM查詢:
- 操作對象來執(zhí)行數(shù)據(jù)庫操作,而不需要編寫原始的 SQL 語句
- 提供了更加 Pythonic 和面向對象的接口,使得代碼更加清晰和易于維護
from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base # 創(chuàng)建引擎 engine = create_engine('mysql+pymysql://root:root@127.0.0.1:3306/easy-admin') # 創(chuàng)建Session Session = sessionmaker(bind=engine) session = Session() # 定義映射類 Base = declarative_base() class User(Base): __tablename__ = 'manong' id = Column(Integer, primary_key=True) name = Column(String(255)) # 在這里指定了 name 列的長度為 255 age = Column(Integer) result = session.query(User).filter(User.age > 18).all() for user in result: print(user.name, user.age)
區(qū)別的方式在于:
- 實現(xiàn)方式:基于 SQL 的查詢直接使用原始的 SQL 語句,而基于 ORM 的查詢則是通過 ORM 工具來執(zhí)行數(shù)據(jù)庫操作
- 編寫方式:基于 SQL 的查詢需要開發(fā)者手動編寫 SQL 語句,而基于 ORM 的查詢則是通過操作對象來執(zhí)行數(shù)據(jù)庫操作,不需要編寫原始的 SQL 語句
- 靈活性:基于 SQL 的查詢更加靈活,可以執(zhí)行復雜的原始 SQL 查詢,而基于 ORM 的查詢提供了更加 Pythonic 和面向對象的接口,使得代碼更加清晰和易于維護
3. ORM CRUD
對于基本的SQL查詢,需要編寫SQL語句,此處偏向實戰(zhàn)類,所以詳細補充ORM CRUD的的基本知識
前半部分代碼如下:
from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base # 創(chuàng)建引擎 engine = create_engine('mysql+pymysql://root:root@127.0.0.1:3306/easy-admin') # 創(chuàng)建Session Session = sessionmaker(bind=engine) session = Session() # 定義映射類 Base = declarative_base() class User(Base): __tablename__ = 'manong' id = Column(Integer, primary_key=True) name = Column(String(255)) # 在這里指定了 name 列的長度為 255 age = Column(Integer) # 創(chuàng)建表 Base.metadata.create_all(engine)
3.1 增加(C)
- 添加單個對象:將新對象添加到數(shù)據(jù)庫中
user = User(name='AA', age=30) session.add(user) session.commit()
- 添加多個對象:將多個新對象批量添加到數(shù)據(jù)庫中
users = [User(name='BB', age=30), User(name='CC', age=25)] session.add_all(users) session.commit()
3.2 查找(R)
查詢所有對象:從數(shù)據(jù)庫中檢索所有對象
all_users = session.query(User).all()
根據(jù)條件查詢:根據(jù)指定條件過濾對象
# # 查詢數(shù)據(jù) result = session.query(User).filter(User.age > 18).all() for user in result: print(user.name, user.age)
查詢單個對象:從數(shù)據(jù)庫中檢索滿足條件的單個對象
user = session.query(User).filter_by(name='Alice').first()
3.3 更新(U)
更新單個對象:修改數(shù)據(jù)庫中的現(xiàn)有對象
user = session.query(User).filter_by(name='Alice').first() user.age = 35 session.commit()
批量更新:使用 update()
方法批量更新滿足條件的對象
session.query(User).filter(User.age < 30).update({'age': 30}) session.commit()
3.4 刪除(D)
刪除單個對象:從數(shù)據(jù)庫中刪除指定的對象
user = session.query(User).filter_by(name='Alice').first() session.delete(user) session.commit()
批量刪除:使用 delete()
方法批量刪除滿足條件的對象
session.query(User).filter(User.age > 30).delete() session.commit()
4. 彩蛋
4.1 建表Bug
建表的過程中如果語句如下:
class Manong(Base): __tablename__ = 'manong' id = Column(Integer) name = Column(String)
報錯信息如下: sqlalchemy.exc.CompileError: (in table 'manong', column 'name'): VARCHAR requires a length on dialect mysql
主要問題如下:
在 MySQL 中,VARCHAR 類型的列必須指定長度,即字符的最大數(shù)量。
需要為表中的 VARCHAR 類型的列指定長度
將其代碼修改為:
from sqlalchemy import Column, Integer, String from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Manong(Base): __tablename__ = 'manong' id = Column(Integer, primary_key=True) name = Column(String(255)) # 在這里指定了 name 列的長度為 255 # 繼續(xù)定義其他列和表結構
如果不是建表,可以省略字段長度
4.2 filter 和 filter_by
filter
方法使用類名和屬性名來構建查詢條件,比較通常使用==
,也可以使用其他比較操作符如>
,<
,>=
,<=
等filter_by
方法直接使用屬性名和相應的值來構建查詢條件,比較通常使用=
以下為簡易Demo,方便理解:
# 使用 filter 方法 from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine) session = Session() # 查詢名字為 Alice 的記錄 alice_records = session.query(User).filter(User.name == 'Alice').all() # 查詢年齡大于等于 25 歲的記錄 older_users = session.query(User).filter(User.age >= 25).all() # 使用 filter_by 方法 # 查詢名字為 Alice 的記錄 alice_records = session.query(User).filter_by(name='Alice').all()
filter 的組合查詢: (這個在實戰(zhàn)中比較常用?。。。?/p>
通過連續(xù)調用來實現(xiàn)多個條件的組合查詢,或者使用AND 條件連接多個條件
# 使用 filter 連續(xù)添加條件查詢 # 查詢名字為 Alice 且年齡大于等于 25 歲的記錄 alice_older_records = session.query(User).filter(User.name == 'Alice').filter(User.age >= 25).all()
或者如下:
from sqlalchemy import and_ # 使用 and_ 函數(shù)連接兩個條件 alice_older_records = session.query(User).filter(and_(User.name == 'Alice', User.age >= 25)).all()
以上就是Python中SQLAlchemy庫的使用方法分析的詳細內(nèi)容,更多關于Python SQLAlchemy庫使用的資料請關注腳本之家其它相關文章!
- 分析解決Python中sqlalchemy數(shù)據(jù)庫連接池QueuePool異常
- 3個Python?SQLAlchemy數(shù)據(jù)庫操作功能詳解
- Python使用SQLAlchemy模塊實現(xiàn)操作數(shù)據(jù)庫
- Python?SQLAlchemy與數(shù)據(jù)庫交互操作完整指南
- Python使用sqlalchemy實現(xiàn)連接數(shù)據(jù)庫的幫助類
- Python中使用sqlalchemy操作數(shù)據(jù)庫的問題總結
- Python使用SQLAlchemy進行復雜查詢的操作代碼
- Python如何使用sqlalchemy實現(xiàn)動態(tài)sql
- python SQLAlchemy 數(shù)據(jù)庫連接池的實現(xiàn)
相關文章
詳解Python Matplotlib解決繪圖X軸值不按數(shù)組排序問題
這篇文章主要介紹了詳解Python Matplotlib解決繪圖X軸值不按數(shù)組排序問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08python3 selenium自動化 frame表單嵌套的切換方法
今天小編就為大家分享一篇python3 selenium自動化 frame表單嵌套的切換方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08python利用pandas將excel文件轉換為txt文件的方法
今天小編就為大家分享一篇python利用pandas將excel文件轉換為txt文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10