iT邦幫忙

2025 iThome 鐵人賽

DAY 29
2

https://ithelp.ithome.com.tw/upload/images/20250902/20177885qdwaDwVmoW.png

在前一天的內容中,我們使用 SQLModel 來定義資料表,並且可以自動建立 Table 與 Index。不過,當專案開發進行到一定程度時,我們可能會遇到修改 table schema,或是管理不同版本的資料庫結構的需求,這時候我們就可以使用 Alembic 來幫助我們進行資料庫的版本控制。

1. 安裝 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

2. 設定 Alembic 連接 PostgreSQL

接下來,我們要讓 Alembic 知道該連接哪個資料庫。在 alembic.ini 中找到 sqlalchemy.url,改成我們的 PostgreSQL 連線:

sqlalchemy.url = postgresql+psycopg://postgres:password@localhost:5432/mydatabase

3. 產生 migration script

當我們想要對資料表進行改動(例如新增欄位),可以使用以下指令來產生 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(),則會刪除該欄位。

4. 執行資料庫 migration

要執行這個變更,我們只需要使用 upgrade 的指令:

alembic upgrade head # 到最新的版本
# or
alembic upgrade [version] # 更新到指定的版本

https://ithelp.ithome.com.tw/upload/images/20250821/20177885UJopGevjXZ.png

如果要回到上一個版本,可以執行:

alembic downgrade -1 # 退回到前一個版本
# or
alembic downgrade [version] # 退回到指定的版本

https://ithelp.ithome.com.tw/upload/images/20250821/20177885vzOve3uWxM.png

5. 在 FastAPI 啟動時自動執行 migration

如果要確保每次啟動 FastAPI 時都會套用最新的 migration,可以修改 main.py,在 lifespan 中加入:

import subprocess

@asynccontextmanager
async def lifespan(app: FastAPI):
	# 執行 alembic migration
	subprocess.run(["alembic", "upgrade", "head"])
	yield

https://ithelp.ithome.com.tw/upload/images/20250919/20177885f8wkivqQx0.png

這樣每次啟動 FastAPI 時,Alembic 會自動更新資料庫結構。在寫 migration script 的時候,可以回想前面有提到的 Lock 相關章節,就可以先預期進行更版的時候,資料庫可能會遇到哪些鎖、哪些操作可能會需要等待。

重點回顧

  • Alembic 可幫助我們進行資料表的版本控制與改動。
  • 透過 alembic revision 來自動產生 migration script 模板,確保變更可以被追蹤。
  • 執行 alembic upgrade head 來套用新的版本,downgrade 來回到之前的版本。

上一篇
Day 28 - 使用 FastAPI + SQLModel 定義 Table 與 Index
下一篇
Day 30 - 用 Alembic 自動產生 migration
系列文
PostgreSQL 效能優化 30 天挑戰:從 Index 到 Transaction 的深入探索30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言