mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-22 13:05:18 +00:00
36 lines
2.0 KiB
Python
36 lines
2.0 KiB
Python
"""迁移一致性守卫 —— create_all 自举产物必须与模型 metadata 零漂移。
|
||
|
||
双轨制风险:新装用户走 create_all + stamp head 路径,存量用户走 alembic upgrade 路径。
|
||
若模型与自举产物漂移,两条路径会产出不同 schema 且无人发现(dev 启动时的自动迁移
|
||
只是隐式守卫,仅在开发者本机生效)。
|
||
|
||
覆盖范围说明:此处校验 SQLite 方言下 create_all 渲染产物 ≡ metadata;
|
||
MySQL 方言的 DDL 渲染差异由 dev 启动时的自动迁移(autogen 零差异检查)承担。
|
||
"""
|
||
|
||
import asyncio
|
||
|
||
from alembic import command
|
||
from alembic.config import Config
|
||
from fastapi.testclient import TestClient
|
||
|
||
from app.config.path_conf import ALEMBIC_VERSION_DIR, BASE_DIR
|
||
|
||
|
||
def test_bootstrap_matches_metadata(test_client: TestClient, versions_before_layout: frozenset[str]) -> None:
|
||
"""守卫一:布局阶段不得产出迁移文件;守卫二:自举库与模型零漂移。"""
|
||
cfg = Config(str(BASE_DIR / "alembic.ini"))
|
||
|
||
# 守卫一:TestClient 布局(init_db)期间,dev 自动迁移不得向仓库 versions/ 写入文件。
|
||
# 布局阶段产出 = create_all 产物与 metadata 存在漂移(被 dev autogen 消化),属污染信号。
|
||
leaked = {p.name for p in ALEMBIC_VERSION_DIR.glob("*.py")} - versions_before_layout
|
||
assert not leaked, f"测试布局阶段产出迁移文件(模型与自举库漂移): {sorted(leaked)}"
|
||
|
||
# 守卫二:显式跑一次 autogenerate,必须零产出(验证布局后的库 ≡ 模型,
|
||
# 同时兜底布局阶段 autogen 失败被 warning 吞掉、库未真正对齐的场景)
|
||
asyncio.run(asyncio.to_thread(command.revision, cfg, autogenerate=True, message="migration-guard"))
|
||
produced = {p.name for p in ALEMBIC_VERSION_DIR.glob("*.py")} - versions_before_layout
|
||
for name in produced: # 清理守卫自身产物,避免污染仓库
|
||
(ALEMBIC_VERSION_DIR / name).unlink()
|
||
assert not produced, f"autogenerate 检出漂移并产出迁移文件: {sorted(produced)}"
|