袁聪的第二次提交,项目已完整
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user