Python中CRUD增刪改查教程

banq發表於2024-06-03

CRUD 是一個縮寫,代表建立(Create)、讀取(Read)、更新(Update)和刪除(Delete),這四個操作是幾乎所有應用程式的核心,它們允許開發者在應用程式中建立、檢索、更新和刪除資料。

以下是關於 CRUD 操作的一些關鍵點:

  1. 建立(Create):向資料庫新增新條目。
  2. 讀取(Read):檢索或檢視資料庫中現有的條目。
  3. 更新(Update):修改資料庫中已有的資料詳細資訊。
  4. 刪除(Delete):從資料庫中移除現有的條目。

CRUD 操作是應用程式功能的基礎,它們影響應用程式如何儲存、檢索和管理資料的每一個方面。理解 CRUD 對於構建應用程式和理解你所使用的應用程式的後臺工作至關重要。

CRUD 操作在 SQL 中幾乎一一對應於 SQL 命令:

  • 建立 對應於 INSERT 命令。
  • 讀取 對應於 SELECT 命令。
  • 更新 對應於 UPDATE 命令。
  • 刪除 對應於 DELETE 命令。

使用 SQLAlchemy 執行 CRUD 操作
SQLAlchemy是 Python 的一個流行物件關係對映器 (ORM)。ORM 允許您使用 Python 物件與資料庫互動,而不是像上一節中那樣編寫原始 SQL 查詢。這讓 Python 開發人員編寫程式碼更加方便。

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import DeclarativeBase, sessionmaker

class Base(DeclarativeBase):
    pass

class Bird(Base):
    __tablename__ = <font>"bird"
    id = Column(Integer, primary_key=True)
    name = Column(String)

    def __repr__(self):
        return f
"Bird(id={self.id}, name={self.name!r})"

engine = create_engine(
"sqlite:///birds.db")
Session = sessionmaker(bind=engine)

def init_db():
    Base.metadata.create_all(engine)

使用 SQLAlchemy 的一個重要優勢是可以宣告模型。在第 7 行中,您建立了一個 Bird 類,它既描述了鳥類資料庫表,又描述了稍後將與表項互動的 Python 物件模型。

透過第 18 行的 init_db(),如果 birds.db 資料庫不存在,則建立它;如果它存在,則連線它。這意味著您可以繼續使用前一節中已有的 birds.db 資料庫來研究 SQLAlchemy 的 CRUD 操作。

從您儲存 crud_sql_alchemy.py 的同一資料夾中啟動另一個 Python REPL 會話。然後,使用 SQLAlchemy 執行第一次 CRUD 操作:

>>> from crud_sql_alchemy import Session, Bird, init_db
>>> init_db()
>>> session = Session()
>>> new_bird = Bird(name=<font>"Test Bird")
>>> session.add(new_bird)
>>> session.commit()

透過 SQLAlchemy,您可以使用會話的 .add() 方法建立新的資料庫條目。在上面的示例中,您將建立一個名稱為 "Test Bird "的新條目。

要檢查資料庫中是否存在 "Test Bird",可以查詢資料庫:

>>> from sqlalchemy import select
>>> query = select(Bird).where(Bird.name == <font>"Test Bird")
>>> bird = session.execute(query).scalar_one()
>>> bird
<Bird(id=3, name='Test Bird')>

要使用 SQLAlchemy 檢索資料庫條目,需要使用 select() 和 .where() 方法。查詢類似於原始 SQL 語句,但 Python 程式碼看起來更熟悉。在這裡,您要選擇名稱等於 "Test Bird "的所有 Bird 物件。

返回將得到一個 Select 物件,並將其儲存在查詢變數中。

將 query 傳遞到 .execute() 時,就會執行查詢。雖然資料庫中只有一個 "Test Bird "符合您的查詢,但您需要使用 .scalar_one() 將這個準確的資料庫條目儲存為 bird。

現在,您已經捕捉到了 "Test Bird",並將物件儲存到了 bird 變數中,您可以繼續更新它的名稱了:

>>> bird.name = <font>"Example Bird"
>>> session.commit()
>>> session.execute(select(Bird)).scalars().all()
[<Bird(id=1, name='Hummingbird')>, <Bird(id=3, name='Example Bird')>]

在 SQLAlchemy 中,更新操作就像更改物件的屬性然後提交更改一樣簡單。為了驗證一切正常,您可以再次查詢資料庫並檢視所有資料庫條目。

在使用 SQLAlchemy 建立、讀取和更新資料庫後,您的 CRUD 例程中只缺少一個操作:刪除條目。

只要您還在會話中,您就可以繼續使用 bird:

>>> session.delete(bird)
>>> session.commit()
>>> session.close()

您可以透過呼叫會話的 .delete() 方法來準備使用 SQLAlchemy 刪除資料庫條目。同樣,您需要呼叫 .commit() 來執行刪除 CRUD 操作。

最後,重置會話是一種好的做法。您可以將 session.close() 視為您的善後工作。

使用 SQLAlchemy 可以透過新增一層抽象層來執行 CRUD 操作,從而降低編寫原始 SQL 的複雜性。在使用網路應用程式時,在執行 CRUD 操作時還可以再增加一層抽象層。

接下來,您將探索 CRUD 操作在網路中的作用,然後構建自己的 CRUD 驅動的 REST API,使用 HTTP 請求方法和 SQLAlchemy 與資料庫互動。

Http方法
CRUD 操作也與 HTTP 請求方法相對應:

  • 建立 對應於 POST 請求。
  • 讀取 對應於 GET 請求。
  • 更新 可以使用 PUT 或 PATCH 請求。
  • 刪除 對應於 DELETE 請求。

使用 FastAPI 執行 CRUD 操作
FastAPI是一個使用 Python 構建 API 的 Web 框架。繼續將 FastAPI 安裝到您之前建立的相同虛擬環境中,並在其中安裝了 SQLAlchemy:

(venv) $ python -m pip install fastapi "uvicorn[standard]"

除了 FastAPI,您還可以使用上述命令安裝Uvicorn。Uvicorn將是您執行 FastAPI 的伺服器。

此外,FastAPI 安裝Pydantic作為其依賴項。Pydantic 將幫助您對資料進行建模。

您將使用 FastAPI 建立要向其傳送 HTTP 請求的端點。端點收到請求後,您將對資料庫執行 CRUD 操作birds.db。

from fastapi import FastAPI, HTTPException, Depends
from sqlalchemy import select
from sqlalchemy.orm import Session
from pydantic import BaseModel, ConfigDict

from crud_sql_alchemy import Bird, init_db
from crud_sql_alchemy import Session as SessionLocal

app = FastAPI()
init_db()

class BirdCreate(BaseModel):
    name: str

class BirdUpdate(BaseModel):
    name: str

class BirdResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    name: str

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

首先,匯入 FastAPI 來建立 Web 應用程式並HTTPException處理潛在錯誤。使用PydanticBaseModel進行資料驗證和設定管理。

在試用 API 之前,您需要定義 CRUD 操作的端點。繼續編輯crud_fastapi.py並新增以下程式碼來定義您的第一個端點:

# ...

@app.post(<font>"/birds/", response_model=BirdResponse)
def create_bird(bird: BirdCreate, db: Session = Depends(get_db)):
    new_bird = Bird(name=bird.name)
    db.add(new_bird)
    db.commit()
    db.refresh(new_bird)
    return new_bird

讀取當前儲存在資料庫中的所有鳥類的端點:

# ...

@app.get(<font>"/birds/", response_model=list[BirdResponse])
def read_birds(db: Session = Depends(get_db)):
    birds = db.execute(select(Bird)).scalars().all()
    return birds

read_birds()函式返回儲存在bird資料庫表中的所有鳥類。此端點響應GET請求,允許您檢索所有鳥類的列表。

如果您只想接收特定的鳥,則需要在響應中告訴 API 您想要獲取哪隻鳥。為此,新增另一個接受鳥id作為引數的端點:

# ...

@app.get(<font>"/birds/{bird_id}", response_model=BirdResponse)
def read_bird(bird_id: int, db: Session = Depends(get_db)):
    query = select(Bird).where(Bird.id == bird_id)
    found_bird = db.execute(query).scalar_one()
    if found_bird is None:
        raise HTTPException(status_code=404, detail=
"Bird not found")
    return found_bird

當您將bird_id作為請求的端點 URL 的一部分傳入時GET,該read_bird()函式會嘗試返回具有給定 ID 的鳥。

上面的 SQLAlchemy 程式碼看起來與您之前在 Python REPL 中執行的步驟類似。

CRUD​​​​​​​更新操作
只有當具有請求 ID 的鳥存在時,您才會繼續更改鳥的名稱:

# ...

@app.put(<font>"/birds/{bird_id}", response_model=BirdResponse)
def update_bird(bird_id: int, bird: BirdUpdate, db: Session = Depends(get_db)):
    query = select(Bird).where(Bird.id == bird_id)
    found_bird = db.execute(query).scalar_one()
    if found_bird is None:
        raise HTTPException(status_code=404, detail=
"Bird not found")
    found_bird.name = bird.name
    db.commit()
    db.refresh(found_bird)
    return found_bird

刪除.delete():

# ...

@app.delete(<font>"/birds/{bird_id}", response_model=dict)
def delete_bird(bird_id: int, db: Session = Depends(get_db)):
    query = select(Bird).where(Bird.id == bird_id)
    found_bird = db.execute(query).scalar_one()
    if found_bird is None:
        raise HTTPException(status_code=404, detail=
"Bird not found")
    db.delete(found_bird)
    db.commit()
    return {
"message": "Bird deleted successfully"}


現在,您的所有 CRUD API 端點都已存在,是時候試用您的 API 了!透過執行命令啟動 Uvicorn 伺服器uvicorn。作為引數,您需要提供不帶.py副檔名的檔名,後跟冒號 ( :) 和 FastAPI 應用程式的名稱:

(venv) $ uvicorn crud_fastapi:app
INFO:     Will watch for changes in these directories: [...]
INFO:     Uvicorn running on http:<font>//127.0.0.1:8000 (Press CTRL+C to quit)<i>
INFO:     Started reloader process [29889] using WatchFiles
INFO:     Started server process [29891]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

FastAPI 的一個很酷的功能是它自帶了開箱即用的互動式 API 文件。這意味著您可以直接在瀏覽器中測試 REST API 端點。訪問http://127.0.0.1:8000/docs並在您的 REST API 上執行一些 CRUD 操作

REST API 中的 CRUD 操作為構建可透過 Web 建立、讀取、更新和刪除資源的 Web 服務提供了標準化框架。

總結
在本教程中,您探索了資料庫和 REST API 中的 CRUD 操作。在用原始 SQL 編寫 CRUD 操作後,您利用 SQLAlchemy 以更直觀的方式與資料庫互動。然後,您使用 FastAPI 建立 REST API 來幫助您瞭解 CRUD 操作如何連線到 HTTP 請求方法。

  • FastAPI 是一款出色的軟體包,可用於將 CRUD 操作與 HTTP 請求方法連線起來。藉助端點,您可以將 CRUD 操作對映到與資料庫互動的函式。
  • 同樣,SQLAlchemy 是一款出色的工具,可幫助您直觀地在資料庫上執行 CRUD 操作。

相關文章