詳解如何使用SQLAlchemy連接數(shù)據(jù)庫(kù)
相對(duì)于 Django 來(lái)說(shuō),F(xiàn)lask 并沒(méi)有 Django 中自帶的那種 ORM 框架,但是我們可以利用第三方的 ORM 框架來(lái)進(jìn)行操作,比如我們這里介紹的 SQLAlchemy。
接下來(lái)這一篇筆記將會(huì)介紹如何使用 SQLAlchemy 連接數(shù)據(jù)庫(kù)、建立模型、操作表、以及查詢操作表數(shù)據(jù)等內(nèi)容。
0、模塊安裝
對(duì)于 SQLAlchemy 來(lái)說(shuō),它還需要使用 pymysql 這個(gè)庫(kù)來(lái)進(jìn)行數(shù)據(jù)庫(kù)的操作,所以這里我們安裝的模塊如下:
pip3 install sqlalchemy==2.0.19 pip3 install pymysql==1.1.0
1、數(shù)據(jù)庫(kù)的連接與使用
以下是使用 SQLAlchemy 對(duì)數(shù)據(jù)庫(kù)進(jìn)行連接以及一個(gè)簡(jiǎn)單的查詢示例:
from sqlalchemy import create_engine, text engine = create_engine("mysql+pymysql://root:123456@192.168.1.5:3306/db_test?charset=utf8") with engine.connect() as conn: sql = "select id, name from users" result = conn.execute(text(sql)) print(result.all()) # [(1, 'admin'), (2, 'user_1')]
在這里,我們預(yù)設(shè)在 db_test
這個(gè)庫(kù)下有一張表名為 users
的表,然后使用原生的 SQL
語(yǔ)句進(jìn)行了查詢和打印操作,這個(gè)操作其實(shí)就跟直接使用 pymysql
模塊操作數(shù)據(jù)庫(kù)沒(méi)有區(qū)別。
如果是插入、更新語(yǔ)句的話,在后面還需要加上 conn.commit()
提交操作。
2、ORM 模型的建立與 ORM Session 的使用
接下來(lái)我們定義一個(gè) ORM 模型,其實(shí)這里的 ORM 模型就跟 Django 的模型類似了,不過(guò)在語(yǔ)法上有一些區(qū)別:
from sqlalchemy.orm import DeclarativeBase from sqlalchemy import Column, Integer, String, Text, DateTime, func class Base(DeclarativeBase): pass class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(50), unique=True, nullable=False, comment="用戶名") email = Column(String(120), default="", comment="郵箱") remark = Column(Text, default="", comment="備注信息") created_time = Column(DateTime, server_default=func.now(), comment="創(chuàng)建時(shí)間") updated_time = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="修改時(shí)間")
在這里,我們定義了一個(gè) Base
類,繼承于 DeclarativeBase
,DeclarativeBase
是用于定義 ORM 模型的基類,提供了一些方便的功能,使得使用 ORM 進(jìn)行數(shù)據(jù)庫(kù)操作更加簡(jiǎn)單和直觀,比如提供了一些 query 的方法,這個(gè)我們后面再介紹。
對(duì)于 User
這個(gè) class
,一個(gè)類似于 Django
的 ORM 的 SQLAlchemy
的 ORM 模型就搭建完成了。
其中,Integer
,String
,Text
,DateTime
這些都是各自對(duì)應(yīng)到數(shù)據(jù)庫(kù)的字段
對(duì)于定義的 Column()
,有很多字段的屬性,比如 primary_key
主鍵,auto_increment
自增,default
默認(rèn)值,nullable
是否允許為 Null
等
在這里,created_time 和 updated_time 實(shí)現(xiàn)的是 Django 的日期時(shí)間字段里 auto_now_add 和 auto_now 屬性,即為創(chuàng)建或者修改的時(shí)候值為當(dāng)前時(shí)間
接下來(lái)介紹一下 ORM Session 的定義,以下是一個(gè)示例:
from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker engine = create_engine("mysql+pymysql://root:123456@192.168.1.5:3306/db_test?charset=utf8") db_session = scoped_session( sessionmaker( autoflush=False, bind=engine ) )
上面的操作中,sessionmaker() 通過(guò) engine 創(chuàng)建了一個(gè)會(huì)話工廠對(duì)象,然后通過(guò) scoped_session() 函數(shù)創(chuàng)建了一個(gè) scoped_session 對(duì)象
我們可以直接使用上面定義出來(lái)的 db_session 對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作,也可以對(duì)其進(jìn)行實(shí)例化后操作:
db_session.do_something() // 直接用 db_session 操作數(shù)據(jù)庫(kù) session = db_session() session.db_something() // 用 db_session 實(shí)例化結(jié)果操作數(shù)據(jù)庫(kù)
他們的使用對(duì)象雖然不同,但在功能上都提供了線程本地的會(huì)話對(duì)象,可以在多線程應(yīng)用程序中安全地使用。
3、表操作
下面介紹一下 SQLAlchemy 如何操作表。
1. 創(chuàng)建表
在前面我們定義了 engine 和 Base 基類和 User 這個(gè)表的 class 之后,我們可以使用下面的方式創(chuàng)建全部定義的表:
Base.metadata.create_all(bind=engine)
執(zhí)行上面的語(yǔ)句之后,User 這個(gè) class 對(duì)應(yīng)的表就會(huì)被創(chuàng)建到數(shù)據(jù)庫(kù)中。
可以把上面這個(gè)語(yǔ)句添加到項(xiàng)目的啟動(dòng)步驟中,因?yàn)檫@個(gè)操作會(huì)創(chuàng)建庫(kù)里沒(méi)有的表,已有的就不會(huì)重復(fù)執(zhí)行了。
2. 修改表結(jié)構(gòu)
SQLAlchemy 不支持通過(guò)函數(shù)的形式直接修改表結(jié)構(gòu),但是可以執(zhí)行原生的 SQL 來(lái)進(jìn)行 ALTER TABLE 的操作。
或者通過(guò)下面的刪除表操作刪除,再進(jìn)行 create_all() 操作,但是這樣的話,原表的數(shù)據(jù)就不存在了。
3. 刪除表
刪除表的操作與創(chuàng)建的方式類似,如下:
Base.metadata.drop_all(bind=engine)
這樣,所有繼承了 Base 基類的表都會(huì)被刪除
如果要執(zhí)行刪除單張表,可以使用 Table 的 drop() 函數(shù):
from sqlalchemy import Table, MetaData meta_data = MetaData() table_name = "users" user_table = Table(table_name, meta_data, autoload_with=engine) user_table.drop(bind=engine)
4、創(chuàng)建表數(shù)據(jù)
1. 創(chuàng)建單條數(shù)據(jù)
u = User(name="admin", email="120@qq.com") db_session.add(u) db_session.commit()
使用 add() 添加,然后進(jìn)行 commit 操作
2. 創(chuàng)建多條數(shù)據(jù)
u1 = User(name="user_1", email="user1@qq.com") u2 = User(name="user_2", email="user2@qq.com") db_session.add_all([u1, u2]) db_session.commit()
批量創(chuàng)建使用 add_all() 函數(shù)。
5、查詢表數(shù)據(jù)
1. 根據(jù)主鍵 id 查詢數(shù)據(jù)
user = db_session.get(User, 1)
返回的 user 就是一個(gè)前面我們定義好的 User 對(duì)象
2. 條件查詢
條件查詢,可以有兩個(gè)操作,一個(gè)是 where(),一個(gè)是 filter(),這兩者在效果上是相同的,都是作用于條件查詢。
比如,我們要查詢 name 字段的值為 "admin" 以及 id 字段的值為 1 的數(shù)據(jù),且返回 id, name, email 字段,可以使用 query() 來(lái)進(jìn)行字段限制,如下操作:
query = db_session.query(User.id, User.name, User.email).filter(User.name == "admin").filter(User.id == 1) query = db_session.query(User.id, User.name, User.email).filter(User.name == "admin").where(User.id == 1) query = db_session.query(User.id, User.name, User.email).where(User.name == "admin").filter(User.id == 1) query = db_session.query(User.id, User.name, User.email).where(User.name == "admin").where(User.id == 1)
如果我們想要一條數(shù)據(jù),可以使用 first(),如果想要符合條件的全部數(shù)據(jù),可以使用 all()
query.first() # (1, 'admin', '120@qq.com') query.all() # [(1, 'admin', '120@qq.com')]
除此之外,我們還可以將 db_session.query_property() 賦值給 Base.query,后面就可以直接通過(guò) User 進(jìn)行查詢操作
Base.query = db_session.query_property() User.query.filter(User.name == "admin").filter(User.id == 1)
然后通過(guò) first() 或者 all() 返回的就是定義的 User 的對(duì)象
6、更新表數(shù)據(jù)
對(duì)于我們獲取到的 ORM 模型實(shí)例,比如我們?cè)谇懊嫱ㄟ^(guò)主鍵 id 獲取到的數(shù)據(jù),或者在 db_session.query() 中不指定字段,直接指定模型獲取到的數(shù)據(jù),我們可以直接對(duì)其字段進(jìn)行修改,然后 commit
user_1 = db_session.get(User, 1) user_1.email = "999@qq.com" db_session.add(user_1) user_2 = db_session.query(User).filter(User.id == 2).first() user_2.email = "888@qq.com" db_session.add(user_2) db_session.commit()
或者我們前面的 query 屬性的方式也可以:
User.query.filter(User.id == 1).update({"email": "19283@qq.com"}) db_session.commit()
7、刪除表數(shù)據(jù)
1. 單條記錄刪除
user = db_session.get(User, 2) db_session.delete(user) db_session.commit()
2. 根據(jù)條件批量刪除
User.query.filter(User.id == 3).delete() db_session.commit()
以上就是詳解如何使用SQLAlchemy連接數(shù)據(jù)庫(kù)的詳細(xì)內(nèi)容,更多關(guān)于SQLAlchemy數(shù)據(jù)庫(kù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5信號(hào)與槽多窗口數(shù)據(jù)傳遞詳細(xì)使用方法與實(shí)例
這篇文章主要介紹了python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5信號(hào)與槽多窗口數(shù)據(jù)傳遞詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下2020-03-03Scala中使用Jsoup庫(kù)處理HTML文檔的案例分析
Scala是一種多范式的編程語(yǔ)言,具有函數(shù)式編程和面向?qū)ο缶幊痰奶攸c(diǎn),同時(shí)也能夠與Java語(yǔ)言完美兼容,它擁有強(qiáng)大的類型推斷、高階函數(shù)、模式匹配等特性,使得代碼更加簡(jiǎn)潔、靈活和易于維護(hù),這篇文章主要介紹了Scala中使用Jsoup庫(kù)處理HTML文檔的案例分析,需要的朋友可以參考下2024-04-04python實(shí)現(xiàn)web應(yīng)用框架之增加動(dòng)態(tài)路由
這篇文章主要介紹web應(yīng)用框架如何添加動(dòng)態(tài)路由,在我們編寫(xiě)的框架中,我們添加動(dòng)態(tài)路由,是使用了正則表達(dá)式,同時(shí)在注冊(cè)的時(shí)候,需要注明該路由是請(qǐng)求路由,文中有詳細(xì)的代碼示例,需要的朋友可以參考下2023-05-05Python數(shù)據(jù)序列化技術(shù)總結(jié)
在現(xiàn)代軟件開(kāi)發(fā)中,數(shù)據(jù)序列化是一個(gè)關(guān)鍵環(huán)節(jié),它允許我們將復(fù)雜的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為可存儲(chǔ)或可傳輸?shù)母袷?,Python提供了多種數(shù)據(jù)序列化技術(shù),每種技術(shù)都有其獨(dú)特的性能優(yōu)勢(shì)和適用場(chǎng)景,本文將詳細(xì)介紹幾種強(qiáng)大的Python數(shù)據(jù)序列化技術(shù),需要的朋友可以參考下2025-03-03python基礎(chǔ)入門(mén)學(xué)習(xí)筆記(Python環(huán)境搭建)
這篇文章主要介紹了python基礎(chǔ)入門(mén)學(xué)習(xí)筆記,這是開(kāi)啟學(xué)習(xí)python基礎(chǔ)知識(shí)的第一篇,夯實(shí)Python基礎(chǔ),才能走的更遠(yuǎn),感興趣的小伙伴們可以參考一下2016-01-01Python隨機(jī)生成身份證號(hào)碼及校驗(yàn)功能
這篇文章主要介紹了Python隨機(jī)生成身份證號(hào)碼及校驗(yàn)功能,文中給大家提到了校驗(yàn)碼計(jì)算方法,需要的朋友可以參考下2018-12-12利用python中pymysql操作MySQL數(shù)據(jù)庫(kù)的新手指南
PyMySQL是在Python3.x版本中用于連接MySQL服務(wù)器的一個(gè)庫(kù),Python2中是使用mysqldb,這篇文章主要給大家介紹了關(guān)于利用python中pymysql操作MySQL數(shù)據(jù)庫(kù)的相關(guān)資料,需要的朋友可以參考下2021-09-09pandas刪除重復(fù)數(shù)據(jù)簡(jiǎn)單方法
這篇文章主要給大家介紹了關(guān)于pandas刪除重復(fù)數(shù)據(jù)的簡(jiǎn)單方法,在數(shù)據(jù)處理過(guò)程中常常會(huì)遇到重復(fù)的問(wèn)題,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07