78 lines
3.2 KiB
Python
78 lines
3.2 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
Schema 表定义迁移完整性属性测试
|
||
|
||
**Validates: Requirements 7.3, 7.6**
|
||
|
||
Property 6: 对于任意现有数据库 schema(billiards_ods、billiards_dws)中的表,
|
||
新 schema(ods、dws)的 DDL 文件中应包含该表的 CREATE TABLE 定义。
|
||
"""
|
||
import os
|
||
import re
|
||
|
||
from hypothesis import given, settings
|
||
from hypothesis.strategies import sampled_from
|
||
|
||
# ── 路径常量 ──────────────────────────────────────────────
|
||
SCHEMAS_DIR = os.path.join(r"C:\NeoZQYY", "db", "etl_feiqiu", "schemas")
|
||
|
||
# 旧 schema 文件(billiards_ods / billiards_dws)
|
||
OLD_ODS_FILE = os.path.join(SCHEMAS_DIR, "schema_ODS_doc.sql")
|
||
OLD_DWS_FILE = os.path.join(SCHEMAS_DIR, "schema_dws.sql")
|
||
|
||
# 新 schema 文件(ods / dws)
|
||
NEW_ODS_FILE = os.path.join(SCHEMAS_DIR, "ods.sql")
|
||
NEW_DWS_FILE = os.path.join(SCHEMAS_DIR, "dws.sql")
|
||
|
||
# ── 解析工具 ──────────────────────────────────────────────
|
||
# 匹配 CREATE TABLE [IF NOT EXISTS] [schema.]table_name
|
||
_CREATE_TABLE_RE = re.compile(
|
||
r"CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?"
|
||
r"(?:[\w]+\.)?(\w+)",
|
||
re.IGNORECASE,
|
||
)
|
||
|
||
|
||
def _extract_table_names(sql_path: str) -> set[str]:
|
||
"""从 SQL 文件中提取所有 CREATE TABLE 的表名(去掉 schema 前缀)。"""
|
||
with open(sql_path, encoding="utf-8") as f:
|
||
content = f.read()
|
||
return {m.group(1).lower() for m in _CREATE_TABLE_RE.finditer(content)}
|
||
|
||
|
||
# ── 预加载表名集合(模块级,只解析一次) ────────────────────
|
||
OLD_ODS_TABLES = sorted(_extract_table_names(OLD_ODS_FILE))
|
||
OLD_DWS_TABLES = sorted(_extract_table_names(OLD_DWS_FILE))
|
||
|
||
NEW_ODS_TABLES = _extract_table_names(NEW_ODS_FILE)
|
||
NEW_DWS_TABLES = _extract_table_names(NEW_DWS_FILE)
|
||
|
||
# 合并旧表名列表,附带来源标记,方便 hypothesis 采样
|
||
_OLD_ODS_TAGGED = [(t, "ods") for t in OLD_ODS_TABLES]
|
||
_OLD_DWS_TAGGED = [(t, "dws") for t in OLD_DWS_TABLES]
|
||
_ALL_OLD_TABLES = _OLD_ODS_TAGGED + _OLD_DWS_TAGGED
|
||
|
||
|
||
# ── 属性测试 ──────────────────────────────────────────────
|
||
@settings(max_examples=100)
|
||
@given(table_info=sampled_from(_ALL_OLD_TABLES))
|
||
def test_old_table_exists_in_new_schema(table_info: tuple[str, str]) -> None:
|
||
"""
|
||
Property 6: Schema 表定义迁移完整性
|
||
|
||
**Validates: Requirements 7.3, 7.6**
|
||
|
||
对于旧 schema 中的任意表,新 schema DDL 中应包含同名 CREATE TABLE 定义。
|
||
"""
|
||
table_name, source = table_info
|
||
|
||
if source == "ods":
|
||
assert table_name in NEW_ODS_TABLES, (
|
||
f"旧 billiards_ods 表 '{table_name}' 在新 ods.sql 中未找到 CREATE TABLE 定义。"
|
||
f"\n新 ods.sql 包含的表: {sorted(NEW_ODS_TABLES)}"
|
||
)
|
||
else:
|
||
assert table_name in NEW_DWS_TABLES, (
|
||
f"旧 billiards_dws 表 '{table_name}' 在新 dws.sql 中未找到 CREATE TABLE 定义。"
|
||
f"\n新 dws.sql 包含的表: {sorted(NEW_DWS_TABLES)}"
|
||
) |