Commit ddbe0048 authored by Data Governance Dev's avatar Data Governance Dev

fix(find-field): 修两个 MySQL 兼容 bug

1. MySQL 8.0 INFORMATION_SCHEMA.COLUMNS 没有 TABLE_COMMENT 列
   - 原查询 SELECT TABLE_COMMENT FROM INFORMATION_SCHEMA.COLUMNS 直接报 1054
   - 改成 LEFT JOIN INFORMATION_SCHEMA.TABLES 拿表注释

2. schema/table 名含 '-' 时 quote_ident 校验失败
   - web3/backend/core/db_adapter.py::quote_ident 用 ^[A-Za-z_][A-Za-z0-9_]*$ 校验
   - 但 MySQL 的 schema/table 名合法可含 '-', 只要用反引号包即可
   - 仅在 skill 脚本 table_row_count() 里给 MySQL 分支走自定义 _safe_mysql_ident,
     其他方言照旧用 quote_ident, 不动通用 db_adapter 逻辑

触发场景: 查 smart-build 库时直接报错; 修完后能正常输出 6 张含 credit_code/uscc 的表
附加: 踩坑已记录到 memory (mysql-information-schema-columns-no-table-comment)
parent 0a4f6eaa
...@@ -127,22 +127,27 @@ def _build_oracle_match_sql(keywords: list[str]) -> tuple[str, tuple]: ...@@ -127,22 +127,27 @@ def _build_oracle_match_sql(keywords: list[str]) -> tuple[str, tuple]:
def _build_mysql_match_sql(keywords: list[str], database: str) -> tuple[str, tuple]: def _build_mysql_match_sql(keywords: list[str], database: str) -> tuple[str, tuple]:
"""MySQL 走 INFORMATION_SCHEMA.COLUMNS(database_name 不需要 UPPER,默认就是)""" """MySQL 走 INFORMATION_SCHEMA.COLUMNS(database_name 不需要 UPPER,默认就是)。
like_clause = " OR ".join([f"LOWER(COLUMN_NAME) LIKE %s" for _ in keywords]) 注意:MySQL 8.0 的 COLUMNS 表里没有 TABLE_COMMENT(它在 TABLES 里),需要 LEFT JOIN。
"""
like_clause = " OR ".join([f"LOWER(c.COLUMN_NAME) LIKE %s" for _ in keywords])
sql = f""" sql = f"""
SELECT SELECT
TABLE_SCHEMA AS owner, c.TABLE_SCHEMA AS owner,
TABLE_NAME AS table_name, c.TABLE_NAME AS table_name,
COLUMN_NAME AS column_name, c.COLUMN_NAME AS column_name,
COLUMN_TYPE AS column_type, c.COLUMN_TYPE AS column_type,
IS_NULLABLE AS nullable, c.IS_NULLABLE AS nullable,
COLUMN_DEFAULT AS column_default, c.COLUMN_DEFAULT AS column_default,
COLUMN_COMMENT AS column_comment, c.COLUMN_COMMENT AS column_comment,
TABLE_COMMENT AS table_comment t.TABLE_COMMENT AS table_comment
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS c
WHERE TABLE_SCHEMA = %s LEFT JOIN INFORMATION_SCHEMA.TABLES t
ON t.TABLE_SCHEMA = c.TABLE_SCHEMA
AND t.TABLE_NAME = c.TABLE_NAME
WHERE c.TABLE_SCHEMA = %s
AND ({like_clause}) AND ({like_clause})
ORDER BY TABLE_NAME, ORDINAL_POSITION ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION
""" """
params = (database,) + tuple(f"%{kw.lower()}%" for kw in keywords) params = (database,) + tuple(f"%{kw.lower()}%" for kw in keywords)
return sql, params return sql, params
...@@ -189,7 +194,19 @@ def _build_dameng_match_sql(keywords: list[str]) -> tuple[str, tuple]: ...@@ -189,7 +194,19 @@ def _build_dameng_match_sql(keywords: list[str]) -> tuple[str, tuple]:
# ── 3. 行数 + 视图溯源 ───────────────────────── # ── 3. 行数 + 视图溯源 ─────────────────────────
def table_row_count(db: DBConnection, owner: str, table_name: str, db_type: str) -> int | str: def table_row_count(db: DBConnection, owner: str, table_name: str, db_type: str) -> int | str:
"""跨方言 COUNT(*)。owner.table 用对应方言的 quote。""" """跨方言 COUNT(*)。owner.table 用对应方言的 quote。
MySQL 的 schema / table 名允许含 `-`(比如 `smart-build`),用反引号包即可;
db_adapter.quote_ident 太严格,这里自己处理 MySQL 的宽松标识符。
"""
def _safe_mysql_ident(name: str) -> str:
if "`" in name or "\n" in name or ";" in name:
raise ValueError(f"非法 MySQL 标识符: {name!r}")
return f"`{name}`"
if db_type == "mysql":
ident_owner = _safe_mysql_ident(owner)
ident_tbl = _safe_mysql_ident(table_name)
else:
from web3.backend.core.db_adapter import quote_ident from web3.backend.core.db_adapter import quote_ident
ident_owner = quote_ident(owner, db_type) ident_owner = quote_ident(owner, db_type)
ident_tbl = quote_ident(table_name, db_type) ident_tbl = quote_ident(table_name, db_type)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment