首頁 > 軟體

Python ORM框架之SQLAlchemy 的基礎用法

2022-03-06 10:00:04

一、SQLAlchemy 介紹

1.1 ORM 的概念

ORM全稱Object Relational Mapping(物件關係對映),通過 ORM 就能使用 python 中的物件運算元據庫(在底層轉換為sql語句),免去sql語句的書寫。

但是,由於抽象程度較高,所以 sql 語句的執行效率比較低,因此有些情況下,還是需要我們親自書寫sql語句。

ORM 是通過以下對應關係,將 python 程式碼轉換為 sql 語句的:

python物件關係型資料庫
類屬性欄位
類的範例物件記錄
範例物件的屬性值記錄的欄位值

1.2 SQLAlchemy介紹

django 中存取資料庫,通常會使用 django 自帶的 ORM(Object Relational Mapping)物件關係對映來存取資料庫,只需要用python的語法來操作物件,就能被自動對映為 sql 語句。

而 SQLAlchemy 則是一個專門的物件關係對映器和 Python SQL工具包,旨在實現高效和高效能的資料庫存取。

1.3 架構

  • Schema / Types: 類到表之間的對映規則。
  • SQL Expression Language :SQL 語句。
  • Engine :引擎。
  • Connection Pooling: 連線池。
  • Dialect: 方言,呼叫不同的資料庫 API(Oracle, postgresql, Mysql) 並執行對應的 SQL語句。

1.4 非同步

SQLAlchemy 在1.4版本之前,通過 greenlet 實現對非同步的支援,而在1.4及之後版本中,新增了 python asyncio 標準庫的支援。所以,這需要 python 直譯器版本在 3.6+。

1.5 安裝

安裝 SQLAlchemy(1.4版本):

pip install SQLAlchemy

如果需要 greenlet 非同步支援:

pip install sqlalchemy[asyncio]

二、SQLAlchemy 快速入門

2.1 建立設定(可選)

這一步不是必要的,但將設定單獨放置一個檔案中,能方便我們管理和修改。

建立一個組態檔,如 settings.py:

DBMS = 'mysql'  # 資料庫管理系統名稱:如 sqlite、mysql、oracle等 
DBAPI = 'pymysql'  # 所使用的 DBAPI(第三方驅動程式),如 pysqlite、pymysql 等

# 下面就是資料庫管理系統的內容:主機IP、埠、使用者名稱、密碼、資料庫
HOST = 'localhost'  
PORT = 3306  
USERNAME = 'root'
PASSWORD = '123456'
DB = 'myclass'

DB_URI = f'{DBMS}+{DBAPI}://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DB}'

2.2 建立引擎和獲取、關閉連線

任何 SQLAlchemy 應用程式的開始都是一個名為 Engine 的物件,它是一個為特定的資料庫伺服器建立一次的全域性物件,可以理解為通過 SQLAlchemy 運算元據庫的連線中心,儲存著連線池。

from sqlalchemy import create_engine
from settings import DB_URI


engine = create_engine(DB_URI)  # 建立引擎
# 也可以直接傳入字串,不使用組態檔
# engine = create_engine("資料庫管理系統名稱+驅動://使用者名稱:密碼@主機IP:埠號/資料庫名稱", echo=True, future=True)

conn = engine.connect()  # 獲取連線
result = conn.execute('SQL語句')  # 執行SQL
print(result.fetchone())  # 列印 SQL 執行結果中的一行
conn.close()  # 關閉連線

create_engine()的其他常用引數:

  • echo:設定為 True,表示將 SQL 記錄到記錄器,該記錄器將 SQL 寫入標準輸出。
  • future:使用2.0風格的引擎和連線 API,以便使用 2.0 版本中的新特性。
  • encoding:預設為 utf-8。
  • pool_size:在連線池中保持開啟的連線數。

2.3 建立 ORM 模型

from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String

# 建立基礎類別
Base = declarative_base()


# 每一個模型類都要繼承 declarative_base() 建立的基礎類別
class User(Base):
    # 定義表名
    __tablename__ = 'users'
    
    # 定義欄位,引數為欄位型別和約束
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String)
    age = Column(Integer)
    sex = Column(String(10))

2.4 建立對談

每次在 python 中執行完操作後,都需要通過 session 提交到資料庫:

from sqlalchemy.orm import sessionmaker

# 建立對談,相當於 Django ORM 的 objects
Session = sessionmaker(bind=engine)
session = Session()

# 執行資料的增刪改查……
# 比如,新增資料
# session.add(模型類(類屬性=值,……))

# 提交
session.commit()
# 關閉session
session.close()

在commit()之前,可以取消對範例物件所做的修改,也就是回滾:

session.rollback()

2.5 建立和刪除表

建立所有表:

Base.metadata.create_all(engin)  

刪除所有表:

Base.metadata.drop_all(engin)

2.6 新增資料

新增資料:

變數名 = 模型類(類屬性=值,……)
session.add(變數名)

批次新增:

session.add_all([
    模型類(類屬性=值,……),
    模型類(類屬性=值,……)
    ……
])

2.7 查詢資料

查詢所有:

變數名 = session.query(模型類).all()

返回模型類範例物件列表。

查詢指定欄位:

變數名 = session.query(模型類.欄位).all()

只獲取返回結果的第一個:

變數名 = session.query(模型類).first()

連表查詢:

變數名 = session.query(模型類1,模型類2).filter(條件).all()

# 如,查詢使用者 ID 及其愛好的 ID
res = session.query(User, Hobby).filter(User.hobby_id == Hobby.id).all()

返回一個元組構成的列表,元組包含兩個範例物件。

過濾:

變數名 = session.query(模型類).filter(條件).all()

# 如,查詢年齡大於18歲的學生名字
res = session.query(Student.name).filter(Student.age >= 18).all()

條件中常用運運算元:

多條件過濾:

# 條件之間預設為 and 關係
變數名 = session.query(模型類).filter(條件1, 條件2……).all()


# 使用 or 
from sqlalchemy import or_
變數名 = session.query(模型類).filter(or_(條件1, 條件2……)).all()

排序:

變數名 = session.query(模型類).order_by(排序依據欄位.desc()).all()     # desc 表示倒序,寫 asc 或不寫就是升序

統計個數:

變數名 = session.query(模型類).count()

切片:

變數名 = session.query(模型類).all()[1:3]

2.8 修改資料

變數名 = session.query(模型類).filter(條件).update({"欄位":值})
# 不要忘記提交

2.9 刪除資料

session.query(模型類).filter(條件).delete()

三、多表操作

下面的內容中,我將稱定義了外來鍵欄位的模型類為被關聯模型,另一個為關聯模型。

3.1 一對多

建立模型:

外來鍵定義在多的一方。

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

class 模型類名稱(Base):
    __tablename__ = '表名'
    
    欄位 = Column(型別,約束)
    ……
    外來鍵欄位 = Column(型別,其他約束,ForeignKey(關聯模型.欄位))  # 重點
    關聯模型名稱小寫 = relationship("關聯模型的名稱",backref="用於反向查詢的名稱")    # 不是欄位,不會在資料庫中建立

新增資料:

# 正向新增
變數名 = 被關聯模型(欄位=值,……,外來鍵欄位=關聯模型(欄位=值……))
session.add(變數名)

# 反向新增
變數名A = 關聯模型(欄位=值,……)
變數名A.backref的值 = [被關聯模型的範例1,被關聯模型的範例2……]
session.add(變數名A)

正向查詢:

先獲取被關聯模型的範例,然後通過範例.外來鍵獲取關聯物件。

反向查詢:

先獲取關聯模型的範例,然後通過範例.backref的值獲取被關聯模型的範例物件。

3.2 多對多

建立模型:

新建中間表,只儲存雙方的對應關係即可。

在其中一方,定義 relationship:

關聯模型類名稱小寫 = relationship("關聯模型類的名稱", secondary='中間表模型類的名稱小寫', backref="用於反向查詢的名稱")    # 不是欄位,不會在資料庫中建立

新增資料:

在雙方建立好資料後,直接在中間表中新增對應關係。

正向、反向查詢:

與一對多模型一致。

到此這篇關於Python ORM框架之SQLAlchemy 的基礎用法的文章就介紹到這了,更多相關SQLAlchemy 的用法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com