在前一天的內容中,我們使用 SQLModel 來定義資料表,並且可以自動建立 Table 與 Index。不過,當專案開發進行到一定程度時,我們可能會遇到修改 table schema,或是管理不同版本的資料庫結構的需求,這時候我們就可以使用 Alembic 來幫助我們進行資料庫的版本控制。
首先,我們需要安裝 Alembic:
poetry add alembic
安裝完成後,在專案根目錄執行以下指令來初始化 Alembic:
alembic init alembic
這會建立一個 alembic 資料夾,結構如下:
fastapi-sqlmodel-postgres
│── alembic/
│ ├── versions/ # 存放版本
│ ├── env.py # Alembic 設定檔
│ ├── script.py.mako # 產生 migration script 時的模板
│ ├── README
│── alembic.ini # Alembic 的主要設定檔
│── fastapi_sqlmodel_postgres/
│── pyproject.toml
接下來,我們要讓 Alembic 知道該連接哪個資料庫。在 alembic.ini 中找到 sqlalchemy.url
,改成我們的 PostgreSQL 連線:
sqlalchemy.url = postgresql+psycopg://postgres:password@localhost:5432/mydatabase
當我們想要對資料表進行改動(例如新增欄位),可以使用以下指令來產生 migration script:
alembic revision -m "Add new column to orders"
這會在 alembic/versions/
底下產生一個 Python 檔案,例如:
alembic/versions/310354c9c4d3_add_new_column_to_orders.py
打開這個檔案,我們可以將 upgrade & downgrade 改成我們要修改的內容,在這裡我們幫 orders 加上新的欄位:
"""Add new column to orders
Revision ID: 310354c9c4d3
Revises:
Create Date: 2025-09-01 14:38:32.076675
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "310354c9c4d3"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
op.add_column("orders", sa.Column("new_column", sa.String(), nullable=True))
def downgrade() -> None:
"""Downgrade schema."""
op.drop_column("orders", "new_column")
這段程式碼會在 orders 表中新增一個 new_column
欄位,如果執行 downgrade()
,則會刪除該欄位。
要執行這個變更,我們只需要使用 upgrade 的指令:
alembic upgrade head # 到最新的版本
# or
alembic upgrade [version] # 更新到指定的版本
如果要回到上一個版本,可以執行:
alembic downgrade -1 # 退回到前一個版本
# or
alembic downgrade [version] # 退回到指定的版本
如果要確保每次啟動 FastAPI 時都會套用最新的 migration,可以修改 main.py
,在 lifespan 中加入:
import subprocess
@asynccontextmanager
async def lifespan(app: FastAPI):
# 執行 alembic migration
subprocess.run(["alembic", "upgrade", "head"])
yield
這樣每次啟動 FastAPI 時,Alembic 會自動更新資料庫結構。在寫 migration script 的時候,可以回想前面有提到的 Lock 相關章節,就可以先預期進行更版的時候,資料庫可能會遇到哪些鎖、哪些操作可能會需要等待。
alembic revision
來自動產生 migration script 模板,確保變更可以被追蹤。alembic upgrade head
來套用新的版本,downgrade 來回到之前的版本。