在了解完資料庫效能的議題後,要怎麼在專案中有效的管理這些 Table 與 Index 呢?最後幾天我們要來以 FastAPI 為範例,搭配使用 SQLModel 來定義我們希望設計的 Table 與 Index。
SQLModel 是由 FastAPI 的作者開發,他是基於 SQLAlchemy 和 Pydantic 的資料庫模型工具,可以用來定義 PostgreSQL 資料表,同時設定 Index 來優化查詢效能。接下來就一起來使用 Poetry 來建立 FastAPI 專案吧!
首先,我們使用 Poetry 來建立專案並管理 Python 套件。
1. 安裝 Poetry
curl -sSL https://install.python-poetry.org | python3 -
或使用 pip 安裝:
pip install poetry
2. 建立 FastAPI 專案
poetry new fastapi-sqlmodel-postgres
cd fastapi-sqlmodel-postgres
這會建立一個新的專案資料夾,結構如下:
fastapi-sqlmodel-postgres
│── fastapi_sqlmodel_postgres # 預設資料夾
│ ├── __init__.py
│ ├── main.py # FastAPI 入口
│── tests # 測試資料夾
│── pyproject.toml # Poetry 依賴管理
可以在 fastapi_sqlmodel_postgres
底下新增 main.py
當作 FastAPI 入口點。
3. 安裝 FastAPI、SQLModel 及 PostgreSQL 相關套件
poetry add fastapi uvicorn sqlmodel psycopg
uvicorn
:ASGI 伺服器
sqlmodel
:ORM
psycopg
:PostgreSQL 連線套件
接下來我們要來設定專案和 PostgresSQL 資料庫連線,以及定義 Table 了!
1. 設定 PostgreSQL 連線
我們假設 PostgreSQL 服務已經運行,並且資料庫名稱為 mydatabase
,使用者帳號為 postgres
,密碼為 password
。
在 fastapi_sqlmodel_postgres/database.py
定義資料庫連線:
from sqlmodel import SQLModel, create_engine, Session
import os
DATABASE_URL = "postgresql+psycopg://postgres:password@localhost:5432/mydatabase"
engine = create_engine(DATABASE_URL, echo=True) # 連線到 PostgreSQL
def create_db_and_tables():
SQLModel.metadata.create_all(engine) # 自動建立 table
def get_session(): # FastAPI 依賴注入,提供 DB 連線
with Session(engine) as session:
yield session
2. 建立 SQLModel 資料表
我們來建立一個 Orders 表,並在 status 欄位上建立 Index。
fastapi_sqlmodel_postgres/models.py
from sqlmodel import SQLModel, Field
class Orders(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
customer_id: str
status: str
__table_args__ = (Index("idx_orders_status", "status"),)
3. 建立 FastAPI 應用程式
在 fastapi_sqlmodel_postgres/main.py
可以加入 lifespan,在專案啟動時執行新增 Table 的操作,以及新增兩支 API。
在 FastAPI 中資料庫連線可以用 Dependency Injection(依賴注入)的方式使用 Depends(get_session)
。
from fastapi import FastAPI, Depends
from contextlib import asynccontextmanager
from sqlmodel import Session, select
from fastapi_sqlmodel_postgres.database import create_db_and_tables, get_session
from fastapi_sqlmodel_postgres.models import Orders
app = FastAPI()
@asynccontextmanager
async def lifespan(app: FastAPI):
# 開始
create_db_and_tables()
yield
# 結束
app = FastAPI(lifespan=lifespan)
@app.post("/orders/") # POST /orders/:新增訂單
def create_order(order: Orders, session: Session = Depends(get_session)):
session.add(order)
session.commit()
session.refresh(order)
return order
@app.get("/orders/") # 查詢所有訂單
def get_orders(session: Session = Depends(get_session)):
return session.exec(select(Orders)).all()
確保 PostgreSQL 正在運行,然後執行以下指令來啟動 FastAPI 應用程式:
poetry shell
uvicorn fastapi_sqlmodel_postgres.main:app --reload
可以看到他會自動執行 CREATE TABLE
的指令,再去資料庫檢查一下是否已經自動新增 orders
的 Table 和 Index:
如果要測試 API,可以到 http://localhost:8000/docs#/
看到 swagger 文件測試。
今天介紹了快速使用 FastAPI + SQLModel 幫資料庫設定 Table & Index,看到這裡可能會有個疑問,如果想要修改或刪除 Table,要怎麼設定呢?明天我們就要來介紹 Alembic 這個工具了~
Depends
),管理 SQLModel 的 Session 來執行資料庫操作。