30 lines
1.2 KiB
Python
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)
|