Python SQLAlchemy庫的使用方法
一、SQLAlchemy簡介
1.1、SQLAlchemy是什么?
sqlalchemy是一個(gè)python語言實(shí)現(xiàn)的的針對關(guān)系型數(shù)據(jù)庫的orm庫。可用于連接大多數(shù)常見的數(shù)據(jù)庫,比如Postges、MySQL、SQLite、Oracle等。
1.2、為什么要使用SQLAlchemy?
它將你的代碼從底層數(shù)據(jù)庫及其相關(guān)的SQL特性中抽象出來。
1.3、SQLAlchemy提供了兩種主要的使用模式
- SQL表達(dá)式語言(SQLAlchemy Core)
- ORM
1.4、應(yīng)該選擇哪種模式?
雖然你使用的框架中已經(jīng)內(nèi)置了ORM,但是希望添加更強(qiáng)大的報(bào)表功能,請選用Core。
如果你想在一個(gè)一模式為中心的視圖中查看數(shù)據(jù)(用戶類似于SQL),請使用Core。
如果你的數(shù)據(jù)不需要業(yè)務(wù)對象,請使用Core。
如果你要把數(shù)據(jù)看作業(yè)務(wù)對象,請使用ORM。
如果你想快速創(chuàng)建原型,請使用ORM。
如果你需要同事使用業(yè)務(wù)對象和其他與問題域無關(guān)的數(shù)據(jù),請組合使用Core和ORM。
1.5、連接數(shù)據(jù)庫
要連接到數(shù)據(jù)庫,需要先創(chuàng)建一個(gè)SQLAlchemy引擎。SQLAlchemy引擎為數(shù)據(jù)庫創(chuàng)建一個(gè)公共接口來執(zhí)行SQL語句。這是通過包裝數(shù)據(jù)庫連接池和方言(不同數(shù)據(jù)庫客戶端)來實(shí)現(xiàn)的。
SQLAlchemy提供了一個(gè)函數(shù)來創(chuàng)建引擎。在這個(gè)函數(shù)中,你可以指定連接字符串,以及其他一些可選的關(guān)鍵字參數(shù)。
from sqlalchemy import create_engine
engine = create_engine('sqlite:///cookies.db')
engine1 = create_engine('sqlite:///:memory:')
engine2 = create_engine('sqlite://///home/cookiemonster/cookies.db')
engine3 = create_engine('sqlite:///c:\\Users\\cookiemonster\\cookies.db')
engine_mysql = create_engine('mysql+pymysql://cookiemonster:chocolatechip', '@mysql01.monster.internal/cookies', pool_recycle=3600)
1.6、模式和類型
為了訪問底層數(shù)據(jù)庫,SQLAlchemy需要用某種東西來代表數(shù)據(jù)庫中的表。為此,可以使用下面三種方法總的一種:
使用用戶定義的Table對象
使用代表數(shù)據(jù)表的聲明式類
從數(shù)據(jù)庫中推斷
二、SQLAlchemy core
SQLAlchemy core定義表結(jié)構(gòu)使用的是1.5中說的第1種方式。table對象包含一系列帶有類型的列和屬性,它們與一個(gè)常見的元數(shù)據(jù)容器相關(guān)聯(lián)。
元數(shù)據(jù)可以看作是一種Table對象目錄。這些表可以通過MetaData.tables來訪問。
2.1、定義表結(jié)構(gòu)
在SQLAlchemy Core中,我們通過Table構(gòu)造函數(shù)來初始化Table對象。我們要在構(gòu)造函數(shù)中提供MetaData對象(元數(shù)據(jù))和表名,任何其他參數(shù)都被認(rèn)為是列對象。列是通過Column()函數(shù)創(chuàng)建的。
from sqlalchemy import create_engine
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy import MedaData
metadata = MetaData()
user = table('user', metadata,
Column(id, Integer(), primary_key=True),
Column(name, String(255)),
)
engine = create_engine('sqlite:///:memory:')
metadata.create_all(engine) # 表的持久化
2.2、插入數(shù)據(jù)
首先創(chuàng)造一條insert語句,用來把小明放入user表中。為此,先調(diào)用user表的insert()方法,然后再使用values()語句,關(guān)鍵字參數(shù)為各個(gè)列及相應(yīng)值:
ins = user.insert().values( id=1, name='小明' ) print(str(ins))
到此僅僅只是創(chuàng)建了一個(gè)inset語句,還沒有真正執(zhí)行呢,接下來執(zhí)行插入操作:
connection = engine.connect() result = connection.execute(ins) print(result.inserted_primary_key)
2.3、查詢數(shù)據(jù)
構(gòu)建查詢時(shí),要用到select函數(shù),它類似于標(biāo)準(zhǔn)SQL SELECT語句。
from sqlalchemy.sql import select s = select([user]) # 可以使用str(s)查看數(shù)據(jù)庫看到的語句 print(str(s)) rp = connection.execute(s) results = rp.fetchall()
2.3.1、ResultProxy
execute()函數(shù)的返回值是一熱ResultProxy對象,它允許使用索引、名稱或Column對象進(jìn)行訪問。
使用ResultProxy處理行
first_row = results[0] first_row[1] first_row.name first_row[user.c.name]
迭代ResultProxy
rp = connection.execute(s) for record in rp: print(record.user_name)
使用方法訪問結(jié)果
rp.first() # 若有記錄,則返回第一個(gè)記錄并關(guān)閉連接 rp.fetchone() # 返回一行,并保持光標(biāo)為打開狀態(tài),以便你做更多獲取調(diào)用 rp.scalar() # 入股查詢結(jié)果是包含一個(gè)列的單條記錄,則返回單個(gè)值
2.3.2、控制查詢中的列數(shù)
s = select([user.c.name]) rp = connection.execute(s) print(rp.keys()) result = rp.first()
2.3.3、排序
s = select([user.c.name]) s = s.order_by(user.c.name) rp = connection.execute(s) for user in rp: print(user.name)
2.3.4、限制返回結(jié)果集的條數(shù)
s = select([user.c.name]) s = s.order_by(user.c.name) s = s.limit(2) rp = connection.execute(s) for user in rp: print(user.name)
2.3.5、內(nèi)置SQL函數(shù)和標(biāo)簽
from sqlalchemy.sql import func s = select([func.sum(user.c.score)]) rp = connection.execute(s) print(rp.scalar())
2.3.6、過濾
對查詢過濾是通過添加where()語句來完成的。
s = select([user]).where(user.c.name == '小明') rp = connection.execute(s) record = rp.first() print(record.items())
這里只是介紹了常用的查詢方法,更多復(fù)雜的查詢請查閱官方文檔。
2.4、更新數(shù)據(jù)
update()方法和前面的insert()方法很相似,它們的語法幾乎完全一樣,但是update()可以指定一個(gè)where()子句,用來指出要更新哪些行。
from sqlalchemy import update u = update(user).where(user.c.name == '小明') u = u.values(name='小華') result = connection.execute(u) print(result.rowcount)
2.5、刪除數(shù)據(jù)
創(chuàng)建刪除語句時(shí),既可以使用delete()函數(shù),也可以使用表的delete()方法。與insert()和update()不同,delete()不接收值參數(shù),只接收一個(gè)可選where子句,用來指定刪除范文。
from sqlalchemy import delete u = delete(user).where(user.c.name == '小華') result = connection.execute(u) print(result.rowcount)
注意:
更多的高級操作:連接、別名、分組、鏈?zhǔn)秸{(diào)用、原始查詢等,請查閱官方文檔。
2.5、事務(wù)
通過connection.begin()開啟一個(gè)事務(wù),返回一個(gè)transaction對象,接下來根據(jù)執(zhí)行的情況調(diào)用transaction.commit()提交修改或者調(diào)用transaction.rollback()回滾操作。
三、SQLAlchemy orm
SQLAlchemy orm定義表結(jié)構(gòu)使用的是1.5中說的第2種方式。通過定義一個(gè)類,它繼承自一個(gè)名為declarative_base的特殊基類。declarative_base把元數(shù)據(jù)容器和映射器(用來把類映射到數(shù)據(jù)表)結(jié)合在一起。
orm使用的類應(yīng)該滿足如下四個(gè)要求:
- 繼承自declarative_base對象。
- 包含__tablename__,這是數(shù)據(jù)庫中使用的表名。
- 包含一個(gè)或多個(gè)屬性,它們都是column對象。
- 確保一個(gè)或多個(gè)屬性組成主鍵。
3.1、定義表結(jié)構(gòu):
from sqlalchemy import create_engine
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(255))
engine = create_engine('sqlite:///')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
3.2、會話(session)
會話是SQLAlchemy ORM和數(shù)據(jù)庫交互的方式。它通過引擎包裝數(shù)據(jù)庫連接,并為通過會話加載或與會話關(guān)聯(lián)的對象提供標(biāo)識映射(identity map)。標(biāo)識映射是一種類似于緩存的數(shù)據(jù)結(jié)構(gòu),它包含由對象表和主鍵確定的一個(gè)唯一的對象列表。會話還包裝了一個(gè)事務(wù),這個(gè)事務(wù)將一直保持打開狀態(tài),直到會話提交或回滾。
為創(chuàng)建會話,SQLAlchemy提供了一個(gè)sessionmaker類,這個(gè)類可以確保在整個(gè)應(yīng)用程序中能夠使用相同的參數(shù)創(chuàng)建會話。sessionmaker類通過創(chuàng)建一個(gè)Session類來實(shí)現(xiàn)這一點(diǎn),Session類是根據(jù)傳遞給sessionmaker工廠的參數(shù)配置的。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///:memory:')
Session = sessionmaker(bind=engine)
session = Session()
3.3、插入
user = User(1, '小明') session.add(user) session.commit()
3.4、查詢
for row in session.query(User): print(row.id, row.name)
注意:session.query()的返回值是Query對象,不能使用它的返回值作為查詢結(jié)果。關(guān)于Query對象的用法,請參閱:https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query
常用Query對象的方法:
q = session.query(User) q.count() # 獲取查詢結(jié)果的數(shù)量 q.all() # 返回查詢結(jié)果的list,會觸發(fā)執(zhí)行SQL查詢 q.get(id) # 根據(jù)primary_key查詢單個(gè)對象 q.as_scalar() # 返回此次查詢的SQL語句
3.4.1、控制查詢中的列數(shù)
print(session.query(user.name).first())
3.4.2、排序
for record in sesssion.query(user).order_by(user.name): print(user.name)
3.4.3、限制返回結(jié)果集的條數(shù)
query = session.query(user).order_by(user.name).[:2] print([result.user_name for result in query])
3.4.4、內(nèi)置SQL函數(shù)和標(biāo)簽
from sqlalchemy import func inv_count = session.query(func.sum(user.name)).scalar() print(inv_count)
3.4.5、過濾
record = session.query(user).filter(user.name == '小華') print(record)
3.5、更新數(shù)據(jù)
query = session.query(user) xm_user = query.filter(user.user_name == '小華').first() xm_user.name = 'robin' session.commit() print(xm_user.quantity)
3.6、刪除數(shù)據(jù)
query = session.query(user) xm_user = query.filter(user.user_name == '小華').first() session.delete(xm_user) session.commit() print(xm_user)
注意:
這里簡單介紹了SQLAlchemy orm的常見用法,更高級的用法請查閱官方文檔。
四、反射
使用反射技術(shù)可以利用先用數(shù)據(jù)庫填充SQLAlchemy對象。
4.1、反射單個(gè)表
創(chuàng)建初始對象:
from sqlalchemy import Metadata, create_engines
metadata = MetaData()
engine = reate_engine('sqlite:///')
反射Artist表
from sqlalchmy impport Table
artist = Table('Artist', metadata, autoload=True, autoload_with=engine)
4.2、反射整個(gè)數(shù)據(jù)庫
metadata.reflect(bind=engine)
參考資料
https://docs.sqlalchemy.org/en/13/core/type_basics.html#generic-types
以上就是Python SQLAlchemy庫的使用方法的詳細(xì)內(nèi)容,更多關(guān)于Python SQLAlchemy庫的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
matplotlib.pyplot畫圖 圖片的二進(jìn)制流的獲取方法
今天小編就為大家分享一篇matplotlib.pyplot畫圖 圖片的二進(jìn)制流的獲取方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05
深入理解Python虛擬機(jī)中復(fù)數(shù)(complex)的實(shí)現(xiàn)原理及源碼剖析
在本篇文章當(dāng)中主要給大家介紹在 cpython 虛擬機(jī)當(dāng)中是如何實(shí)現(xiàn) 復(fù)數(shù) complex 這個(gè)數(shù)據(jù)類型的,這個(gè)數(shù)據(jù)類型在 cpython 當(dāng)中一應(yīng)該是一個(gè)算比較簡單的數(shù)據(jù)類型了,非常容易理解2023-03-03
實(shí)現(xiàn)python?namedtuple元類編程
這篇文章主要為大家介紹了實(shí)現(xiàn)python?namedtuple元類編程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
使用Python實(shí)現(xiàn)嵌套繪圖并為條形圖添加自定義標(biāo)注
論文繪圖時(shí)經(jīng)常需要多圖嵌套,正好最近繪圖用到了,所以這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)嵌套繪圖并為條形圖添加自定義標(biāo)注,感興趣的可以了解下2024-02-02
Python reduce函數(shù)作用及實(shí)例解析
這篇文章主要介紹了Python reduce函數(shù)作用及實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
python中實(shí)現(xiàn)php的var_dump函數(shù)功能
這篇文章主要介紹了python中實(shí)現(xiàn)php的var_dump函數(shù)功能,var_dump函數(shù)在PHP中調(diào)試時(shí)非常實(shí)用,本文介紹在Python中實(shí)現(xiàn)這個(gè)函數(shù),需要的朋友可以參考下2015-01-01

