目標:當遷移歷史混亂或想用現有模型重新建立「乾淨」的初始遷移時,安全地重置 Alembic 狀態並升到最新。

# TL;DR — 指令清單

# 1 生成初始 migration

alembic revision --autogenerate -m "initial migration"

# 2 執行 migration(創建表格)

alembic upgrade head

# 3 刪除所有遷移檔案(如已刪除可跳過

rm -f alembic/versions/*.py
rm -rf alembic/versions/__pycache__

# 4 清理資料庫版本記錄(Docker 版)

docker exec my_app-postgres-1  psql -U username -d my_app  -c "DELETE FROM alembic_version;"

非 Docker 版本可用:
psql -h 127.0.0.1 -U username -d my_app -c "DELETE FROM alembic_version;"

# 5 檢查 Alembic 狀態(指定設定檔)

alembic -c alembic.ini current
# 預期:沒有版本記錄(空白)

# 6 再次生成「初始遷移」檔案

alembic revision --autogenerate -m "initial migration"

# 7 執行遷移

alembic upgrade head

# 8 確認歷史

alembic history

# 詳細步驟與說明

# Step 1–2:先用現有模型嘗試產生與執行初始遷移

確定 migrations/env.py(或 alembic/env.py)內的:

# 要指向你的 SQLAlchemy Declarative Base
target_metadata = Base.metadata

已設定正確,並能偵測到模型差異。alembic upgrade head 會將 DB 升到最新。

# Step 3:刪除舊遷移檔

清空 alembic/versions/,避免舊遷移歷史干擾(務必先備份或在版本控制中操作)。

# Step 4:清理 DB 的 Alembic 版本表

alembic_version 通常僅有一列紀錄目前版本。用 DELETE 清空即可。

如果這張表不存在,代表 DB 未受 Alembic 管理,可跳過或稍後用 alembic stamp 對齊。

# Step 5:確認狀態

alembic current 應無輸出(表示 DB 目前未標記任何遷移版本)。

# Step 6–7:重新產生並執行「初始遷移」

--autogenerate 會根據 target_metadata 與資料庫現況比對產生遷移腳本。請務必審閱遷移檔(欄位型別、索引、約束),再 upgrade head

# Step 8:檢視歷史

alembic history 應只顯示你的「初始遷移」與後續新增的遷移(若有)。


# 注意事項 / 小陷阱

  • 先備份:清遷移與改 DB 前,請先 pg_dump(或備份資料卷),避免不可逆損失。

  • autogenerate 不是全能:對 trigger、部分複雜 constraint 或 server_default 等,可能無法自動偵測,需手動補上。

  • SQLite 例外多:欄位變更常走「建新表 → 搬資料 → 刪舊表」策略;Alembic 會用 batch mode 協助但仍需審閱。

  • 版本標記 vs. 真正遷移:若 DB schema 已手動對齊,只想「告訴 Alembic 目前是最新」,可改用:

    alembic stamp head

    這不會執行任何 SQL,只會寫入版本表。

  • 多人開發分支:若 alembic heads 顯示多個 head,需先 alembic merge -m "merge heads" <revA> <revB> 合併,再 upgrade head

  • 設定檔路徑:多環境時可用 -c path/to/alembic.ini 指定;多 DB 則可用 -n <section> 選擇命名段落。

  • 傳遞自訂參數alembic -x key=value ... 可在 env.pycontext.get_x_argument(as_dictionary=True) 讀取(例如 -x schema=public)。


# 驗證清單


# 參考補充指令

  • 顯示詳細歷史:

    alembic history --verbose
  • 顯示指定版本資訊:

    alembic show <rev>
  • 只產出 SQL(不執行):

    alembic upgrade head --sql > upgrade.sql
    alembic downgrade -1 --sql > downgrade.sql

以上流程親測適用:Docker + PostgreSQL(容器名 my_app-postgres-1、DB my_app、使用者 username)。依你的環境調整容器名、帳號與資料庫名稱即可。