袁聪的第二次提交,项目已完整

This commit is contained in:
2026-09-11 16:57:47 +08:00
parent 5907fcd6d2
commit fd9598efdf
190 changed files with 31513 additions and 680 deletions
+37 -4
View File
@@ -9,6 +9,14 @@ SOURCE = ROOT / "docs" / "00-新数据库基线设计.md"
SPECIAL_SOURCE = ROOT / "docs" / "02-数据库建表设计.md"
OUTPUT = ROOT / "alembic" / "baseline_generated.sql"
# 文档以两种写法声明唯一约束:
# 1) 显式联合键:| product_id | ... | 唯一键 `(product_id, trade_date)` |
# 2) 联合标记: | customer_id | ... | 联合唯一键、索引 |(同表内多字段共同构成一个键)
# 单列唯一键只在规则列出现"唯一"且未参与上述两种写法时生成。
COMBINED_KEY_RE = re.compile(r"唯一键[^()]*\(([^)]+)\)")
COMBINED_FLAG = "联合唯一键"
MAX_INDEX_NAME = 64
TYPE_MAP = {"BIGINT UNSIGNED": "BIGINT UNSIGNED", "INT": "INT", "FLOAT": "FLOAT",
"TINYINT(1)": "TINYINT(1)", "JSON": "JSON", "DATE": "DATE", "DATETIME": "DATETIME",
"TEXT": "TEXT", "MEDIUMTEXT": "MEDIUMTEXT"}
@@ -61,7 +69,9 @@ def parse_detailed_tables(text: str) -> list[str]:
if not fields:
continue
columns = []
uniques = []
combined_keys: list[tuple[str, ...]] = []
combined_flags: list[str] = []
single_uniques: list[str] = []
indexes = []
for field, typ, rule in fields:
col = f"`{field}` {typ}"
@@ -69,8 +79,21 @@ def parse_detailed_tables(text: str) -> list[str]:
if "CURRENT_TIMESTAMP" in rule and "DATETIME" in typ:
cs.append("DEFAULT CURRENT_TIMESTAMP")
columns.append(col + (" " + " ".join(cs) if cs else " NULL"))
if "唯一" in rule:
uniques.append(field)
matched_key = False
for raw in COMBINED_KEY_RE.findall(rule):
key_columns = tuple(
dict.fromkeys(c.strip().strip("`") for c in raw.split(",") if c.strip())
)
if len(key_columns) > 1:
if key_columns not in combined_keys:
combined_keys.append(key_columns)
elif key_columns:
single_uniques.append(key_columns[0])
matched_key = True
if COMBINED_FLAG in rule:
combined_flags.append(field)
elif "唯一" in rule and not matched_key:
single_uniques.append(field)
if "索引" in rule:
indexes.append(field)
if not any("PRIMARY KEY" in c for c in columns):
@@ -78,7 +101,17 @@ def parse_detailed_tables(text: str) -> list[str]:
if c.startswith("`id`") or c.startswith("`customer_id`") and name == "fin_customer_profile":
columns[n] += " PRIMARY KEY"
break
for field in uniques:
if combined_flags:
flag_columns = tuple(dict.fromkeys(combined_flags))
if len(flag_columns) > 1 and flag_columns not in combined_keys:
combined_keys.append(flag_columns)
for key_columns in combined_keys:
key_name = f"uk_{name}_" + "_".join(key_columns)
if len(key_name) > MAX_INDEX_NAME:
key_name = key_name[:MAX_INDEX_NAME]
rendered = ", ".join(f"`{column}`" for column in key_columns)
columns.append(f"UNIQUE KEY `{key_name}` ({rendered})")
for field in dict.fromkeys(single_uniques):
if not any(f"`{field}`" in c and "PRIMARY KEY" in c for c in columns):
columns.append(f"UNIQUE KEY `uk_{name}_{field}` (`{field}`)")
for field in indexes: