47 lines
2.0 KiB
Python
47 lines
2.0 KiB
Python
"""模型 ↔ SQL dump 建表结构一致性契约测试。
|
||
|
||
document/djangoadmin.fastapi.antdvue.sql 是建表事实来源
|
||
(scripts/init_db.py 以 SQL 为准、模型仅 backfill),因此 SQLAlchemy 模型
|
||
metadata 必须与 SQL 建表语句保持一致,否则 ORM 读写与建表脚本会产生隐蔽漂移。
|
||
|
||
对比维度:表集合、列名集合、每列 (类型族, 长度, 可空)、每表主键集合。
|
||
忽略:default/server_default、字符集、排序规则、显示宽度、索引、自增起始值。
|
||
"""
|
||
import pytest
|
||
|
||
from tests.contract.helpers import collect_model_schema, collect_sql_schema
|
||
|
||
pytestmark = pytest.mark.contract
|
||
|
||
|
||
def test_table_sets_match():
|
||
sql_schema, _ = collect_sql_schema()
|
||
model_schema, _ = collect_model_schema()
|
||
assert set(sql_schema) == set(model_schema), (
|
||
f"表集合不一致!\n"
|
||
f"仅SQL存在: {sorted(set(sql_schema) - set(model_schema))}\n"
|
||
f"仅模型存在: {sorted(set(model_schema) - set(sql_schema))}"
|
||
)
|
||
|
||
|
||
def test_columns_and_types_match():
|
||
sql_schema, sql_pk = collect_sql_schema()
|
||
model_schema, model_pk = collect_model_schema()
|
||
assert set(sql_schema) == set(model_schema), "表集合不一致,先修复表集合再对比列"
|
||
for table in sorted(sql_schema):
|
||
sql_cols = set(sql_schema[table])
|
||
model_cols = set(model_schema[table])
|
||
assert sql_cols == model_cols, (
|
||
f"[{table}] 列名不一致!\n"
|
||
f"仅SQL存在: {sorted(sql_cols - model_cols)}\n"
|
||
f"仅模型存在: {sorted(model_cols - sql_cols)}"
|
||
)
|
||
for col in sorted(sql_cols):
|
||
assert sql_schema[table][col] == model_schema[table][col], (
|
||
f"[{table}.{col}] 定义不一致: SQL={sql_schema[table][col]} "
|
||
f"模型={model_schema[table][col]}"
|
||
)
|
||
assert sql_pk[table] == model_pk[table], (
|
||
f"[{table}] 主键不一致: SQL={sorted(sql_pk[table])} 模型={sorted(model_pk[table])}"
|
||
)
|