首页 > 解决方案 > SQLAlchemy,如何创建上下文感知的自定义编译

问题描述

我希望能够以不同的方式将 SQLAlchemy 查询编译为 SQL 查询;如何编译 不同的 count 与count不同?

当我有选择计数

sql.select([sql.func.count(c1)]).select_from(t1)

结果应该是

select count(c1) from t1

但是当我计数不同时,例如

sql.select([sql.func.count(c1.distinct())]).select_from(t1)

结果应该是

select count(1) from t1 ; 

标签: pythonsqlalchemy

解决方案


为了匹配COUNT(DISTINCT ...),您需要覆盖编译Function

import copy

from sqlalchemy import func

from sqlalchemy.ext.compiler import compiles

from sqlalchemy.sql import operators
from sqlalchemy.sql.expression import literal, Function, UnaryExpression

@compiles(Function)
def visit_function(f, compiler, **kw):
    clauses = f.clauses.clauses

    if f.name.lower() == 'count' \
            and len(clauses) == 1 \
            and isinstance(clauses[0], UnaryExpression) \
            and clauses[0].operator is operators.distinct_op:
        f = func.count(1)

    return compiler.visit_function(f, **kw)

推荐阅读