Files
yunke/yunke-server/app/db/compat.py
T
浅念 00ae13b5c2 feat(deploy): 完成数据迁移与MySQL全链路(14表698k消息100%一致+5方言补丁+bind mount)
- migrate_sqlite_to_mysql.py: 逐表清空重导(幂等),复用repos强转,JSON列
  解析,67万消息按msg_id键集分批,467s跑完14表全一致
- 修4个MySQL实测bug: NULLS LAST语法(compat.py编译补丁)、message.text
  TEXT→MEDIUMTEXT(64KB字节上限,实测20.8万字符车源清单)、URL列
  String(1024)→Text(分享链接超1KB)、垃圾超长member_id源头清理
- compose: media改bind mount(不占C盘Docker虚拟磁盘,实测2.5GB卷把
  C盘撑爆引擎500);mysql不映射宿主机3306
- 前端Dockerfile: npm ci→install(本地/容器npm版本锁漂移)
- 五服务实测:nginx→backend→MySQL全链路返回真实数据(客户6859/A**杰25条
  /搜索56条),媒体49536文件bind mount直读

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-22 12:40:44 +08:00

30 lines
1.2 KiB
Python

"""MySQL 方言兼容补丁(2026-08-22 部署实测发现)。
MySQL 不支持 ``NULLS LAST`` / ``NULLS FIRST`` 语法(SQLite/PostgreSQL 有)。
本项目所有 ``ORDER BY x DESC NULLS LAST`` 在 MySQL 下语义天然一致——
MySQL 的 DESC 排序 NULL 本来就排最后——所以编译时直接剥掉该子句。
ASC + NULLS LAST 的组合如果将来出现,需要改为 ``ORDER BY x IS NULL, x``
(MySQL 惯用法),当前代码库没有这种用法。
"""
from __future__ import annotations
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.elements import UnaryExpression
@compiles(UnaryExpression, "mysql")
def _mysql_strip_nullslast(element, compiler, **kw):
"""MySQL: 剥掉 NULLS LAST/NULLS FIRST。
``sa.nullslast(x.desc())`` 编译为 ``UnaryExpression(modifier=NullsLast)``;
MySQL DESC 下 NULL 天然在末尾(语义等价),直接输出内层表达式。
非 NULLS 修饰的 UnaryExpression(如普通 -x)不受影响——modifier 为 None
时走原编译路径。
"""
from sqlalchemy.sql.operators import nulls_last_op
if element.modifier is not nulls_last_op:
return compiler.visit_unary(element, **kw)
return compiler.process(element.element, **kw)