目標:當遷移歷史混亂或想用現有模型重新建立「乾淨」的初始遷移時,安全地重置 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.py用context.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)。依你的環境調整容器名、帳號與資料庫名稱即可。
