Files
FinDataHub/Scripts
FinDataHub c6d3556b4b fix(data): 统一三库 collation(81 张表),跨库 UNION/JOIN 恢复可用
缺陷(P0-6 的后半部分)
----------------------
日期格式统一后,跨库查询仍报:
  ERROR 1271 (HY000): Illegal mix of collations for operation 'UNION'
原因是列的 collation 不同:
  tushare_data      63 张表  utf8mb4_unicode_ci
  akshare_data      18 张表  utf8mb4_unicode_ci(库内自身也不一致)
  fin_data_clean    全部     utf8mb4_0900_ai_ci
跨源对账/双源比对因此无法用原生 SQL 完成。

前置条件(本次已满足)
----------------------
collation 变更 MySQL **只能走 COPY 算法(整表重建)**,期间该表禁止写入,
且不可回退 —— 因此先做了完整备份:
  ~/Library/Application Support/FinDataHub/backups/db-20260918-235703/
    tushare_data.sql.gz     1.9G   CRC OK, CREATE TABLE 65 条(与本库表数一致)
    akshare_data.sql.gz     496M   CRC OK, 43 条
    fin_data_clean.sql.gz   416M   CRC OK, 14 条
备份可用性经 gzip -t 与建表语句计数双重校验。

改动
----
新增 Scripts/bin/migrate_collation.py:
  --report 输出待转换清单(按体积升序)
  --execute 逐表 ALTER ... CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci
            每表记录前后 collation、行数、残留异类列数;任一异常即 fail-fast
  --verify 独立复核 + 端到端跑跨库 UNION/JOIN
选 utf8mb4_0900_ai_ci 为目标:MySQL 8 默认,且 3 个库中 2 个已经是它。

迁移结果(实测)
----------------
  转换 81 张表,总耗时 336.9 秒,**0 失败**
  每张表行数前后完全一致(如 stock_daily 8,046,947 → 8,046,947)
  残留异类列全部为 0
  复验:三库 65+43+14 = 122 张表全部符合目标

效果(实测,无需任何显式 COLLATE)
----------------------------------
  跨库 UNION          : ✓ 返回 2 行
  跨库 JOIN 同标的对账 : ✓ 命中 5,547 行(akshare/tushare 同日同标的)
  → 跨源校验通路恢复;此前需在每条 JOIN 上写 COLLATE 才能绕过

回归
----
core 121 / tushare 174 / akshare 183 / Scripts 207 / kuaixun 407 = 1092 passed
银层迁移冒烟(表重建后下游):stock_weekly 11,262 行写入成功,blocked=False,质量分 0.85
2026-09-19 00:21:44 +08:00
..