fix: 统一数据库表排序规则
This commit is contained in:
+4
-1
@@ -445,7 +445,10 @@ class DatabaseManager:
|
|||||||
mysql_type = self.TYPE_MAPPING.get(col_type, 'VARCHAR(255)')
|
mysql_type = self.TYPE_MAPPING.get(col_type, 'VARCHAR(255)')
|
||||||
column_defs.append(f'`{col}` {mysql_type}')
|
column_defs.append(f'`{col}` {mysql_type}')
|
||||||
|
|
||||||
sql = f"CREATE TABLE IF NOT EXISTS `{table_name}` ({', '.join(column_defs)}) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
|
sql = (
|
||||||
|
f"CREATE TABLE IF NOT EXISTS `{table_name}` ({', '.join(column_defs)}) "
|
||||||
|
"ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
|
||||||
|
)
|
||||||
|
|
||||||
with self.get_connection() as conn:
|
with self.get_connection() as conn:
|
||||||
with conn.cursor() as cursor:
|
with conn.cursor() as cursor:
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ class CellDataProcessor:
|
|||||||
`功率` varchar(100) DEFAULT NULL,
|
`功率` varchar(100) DEFAULT NULL,
|
||||||
`网络` varchar(20) DEFAULT NULL,
|
`网络` varchar(20) DEFAULT NULL,
|
||||||
KEY `CGI` (`CGI`)
|
KEY `CGI` (`CGI`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -548,9 +548,17 @@ def copy_celldata_tables_to_capacity(app_config: AppConfig, logger=None) -> int:
|
|||||||
logger.info("CellData 数据库中没有表,跳过复制")
|
logger.info("CellData 数据库中没有表,跳过复制")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
target_charset, target_collation = _database_charset_and_collation(cap_conn)
|
||||||
copied = 0
|
copied = 0
|
||||||
for table in tables:
|
for table in tables:
|
||||||
rows = _copy_one_table(cd_conn, cap_conn, table, logger)
|
rows = _copy_one_table(
|
||||||
|
cd_conn,
|
||||||
|
cap_conn,
|
||||||
|
table,
|
||||||
|
target_charset,
|
||||||
|
target_collation,
|
||||||
|
logger,
|
||||||
|
)
|
||||||
if rows >= 0:
|
if rows >= 0:
|
||||||
copied += 1
|
copied += 1
|
||||||
cap_conn.commit()
|
cap_conn.commit()
|
||||||
@@ -571,7 +579,28 @@ def _list_tables(conn) -> list[str]:
|
|||||||
return [list(row.values())[0] for row in cur.fetchall()]
|
return [list(row.values())[0] for row in cur.fetchall()]
|
||||||
|
|
||||||
|
|
||||||
def _copy_one_table(src_conn, dst_conn, table: str, logger=None) -> int:
|
def _database_charset_and_collation(conn) -> tuple[str, str]:
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(
|
||||||
|
"SELECT @@character_set_database AS `charset_name`, "
|
||||||
|
"@@collation_database AS `collation_name`"
|
||||||
|
)
|
||||||
|
row = cur.fetchone()
|
||||||
|
charset = str(row["charset_name"])
|
||||||
|
collation = str(row["collation_name"])
|
||||||
|
if not re.fullmatch(r"[A-Za-z0-9_]+", charset) or not re.fullmatch(r"[A-Za-z0-9_]+", collation):
|
||||||
|
raise RuntimeError("目标数据库字符集或排序规则名称无效")
|
||||||
|
return charset, collation
|
||||||
|
|
||||||
|
|
||||||
|
def _copy_one_table(
|
||||||
|
src_conn,
|
||||||
|
dst_conn,
|
||||||
|
table: str,
|
||||||
|
target_charset: str,
|
||||||
|
target_collation: str,
|
||||||
|
logger=None,
|
||||||
|
) -> int:
|
||||||
with src_conn.cursor() as cur:
|
with src_conn.cursor() as cur:
|
||||||
cur.execute(f"SHOW CREATE TABLE `{table}`")
|
cur.execute(f"SHOW CREATE TABLE `{table}`")
|
||||||
row = cur.fetchone()
|
row = cur.fetchone()
|
||||||
@@ -584,6 +613,10 @@ def _copy_one_table(src_conn, dst_conn, table: str, logger=None) -> int:
|
|||||||
with dst_conn.cursor() as cur:
|
with dst_conn.cursor() as cur:
|
||||||
cur.execute(f"DROP TABLE IF EXISTS `{table}`")
|
cur.execute(f"DROP TABLE IF EXISTS `{table}`")
|
||||||
cur.execute(create_sql)
|
cur.execute(create_sql)
|
||||||
|
cur.execute(
|
||||||
|
f"ALTER TABLE `{table}` CONVERT TO CHARACTER SET {target_charset} "
|
||||||
|
f"COLLATE {target_collation}"
|
||||||
|
)
|
||||||
|
|
||||||
if count == 0:
|
if count == 0:
|
||||||
if logger:
|
if logger:
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ CREATE TABLE IF NOT EXISTS `cellinfo` (
|
|||||||
`功率` varchar(100) DEFAULT NULL,
|
`功率` varchar(100) DEFAULT NULL,
|
||||||
`网络` varchar(20) DEFAULT NULL,
|
`网络` varchar(20) DEFAULT NULL,
|
||||||
KEY `CGI` (`CGI`)
|
KEY `CGI` (`CGI`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ CREATE TABLE IF NOT EXISTS `sector` (
|
|||||||
`站型` varchar(50) DEFAULT NULL,
|
`站型` varchar(50) DEFAULT NULL,
|
||||||
`网络` varchar(20) DEFAULT NULL,
|
`网络` varchar(20) DEFAULT NULL,
|
||||||
KEY `CGI` (`CGI`)
|
KEY `CGI` (`CGI`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ CREATE TABLE IF NOT EXISTS `sector_band_ref` (
|
|||||||
`PLMN` varchar(16) DEFAULT NULL,
|
`PLMN` varchar(16) DEFAULT NULL,
|
||||||
`制式` varchar(20) DEFAULT NULL,
|
`制式` varchar(20) DEFAULT NULL,
|
||||||
`频段` varchar(20) DEFAULT NULL
|
`频段` varchar(20) DEFAULT NULL
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|
||||||
INSERT INTO `sector_band_ref` (`网络`,`频点下限`,`频点上限`,`PLMN`,`制式`,`频段`) VALUES
|
INSERT INTO `sector_band_ref` (`网络`,`频点下限`,`频点上限`,`PLMN`,`制式`,`频段`) VALUES
|
||||||
('5G',4000,99999,NULL,'4.9G','4.9G'),
|
('5G',4000,99999,NULL,'4.9G','4.9G'),
|
||||||
|
|||||||
@@ -1112,3 +1112,10 @@ CellData 处理日志细化(`app/services/cell_data.py`):
|
|||||||
- 全脚本审计覆盖 32 个表标识:配置输入、脚本内建表和线上实际表之间无剩余大小写错配/冲突,且按 157 条语句执行顺序检查无“表尚未创建便引用”和未加反引号的表名。
|
- 全脚本审计覆盖 32 个表标识:配置输入、脚本内建表和线上实际表之间无剩余大小写错配/冲突,且按 157 条语句执行顺序检查无“表尚未创建便引用”和未加反引号的表名。
|
||||||
- 修复镜像 `capacityrepost-web:c054b48` 已部署并重启 Web;MySQL 和旧实例未重启。线上以同一数据库执行第 126、127 条核心查询通过,移动/广电临时校验结果分别为 23,227/23,107 行,临时表已删除。
|
- 修复镜像 `capacityrepost-web:c054b48` 已部署并重启 Web;MySQL 和旧实例未重启。线上以同一数据库执行第 126、127 条核心查询通过,移动/广电临时校验结果分别为 23,227/23,107 行,临时表已删除。
|
||||||
- 自动调度保持启用,正式任务 `20260806_170846` 已启动;因完整处理耗时较长,后续结果由用户自行观察。
|
- 自动调度保持启用,正式任务 `20260806_170846` 已启动;因完整处理耗时较长,后续结果由用户自行观察。
|
||||||
|
|
||||||
|
## 2026-08-06:统一 CellData 与容量库排序规则
|
||||||
|
|
||||||
|
- 第 136 条 SQL 的 1267 错误来自跨表 CGI 关联:容量结果表使用 `utf8mb4_unicode_ci`,CellData 复制来的 `sector/cellinfo` 保留源表 `utf8mb4_0900_ai_ci`;第 136-139 条四个 CGI/NCGI 关联均有同类风险。
|
||||||
|
- `copy_celldata_tables_to_capacity` 在目标空表创建后、插入前读取目标数据库的 `@@character_set_database/@@collation_database` 并执行 `ALTER TABLE ... CONVERT`,复制表不再继承不兼容的源排序规则;字符集和排序规则名称限定为字母数字下划线。
|
||||||
|
- `CellDataProcessor`、`DatabaseManager` 和三份 `db_init` 建表 SQL 均显式使用 `utf8mb4_unicode_ci`,避免 MySQL 8 在只写 `DEFAULT CHARSET=utf8mb4` 时回落到 `utf8mb4_0900_ai_ci`。
|
||||||
|
- 线上 `celldata` 与 `CapacityReport` 两库的 `sector/cellinfo` 已迁移为 `utf8mb4_unicode_ci`;4G/5G 结果表分别关联 sector/cellinfo 的四组真实查询均通过。自动重试任务 `20260806_180436` 保持运行,未重启容器。
|
||||||
|
|||||||
Reference in New Issue
Block a user