You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLAlchemy ORM查询中如何实现可选动态字段功能

问题背景

需要在SQL Server环境下基于SQLAlchemy实现动态ORM查询,其中roles.name模糊匹配、roles.active状态过滤、排序规则均为非必填动态参数,对应原生SQL语句如下:

SELECT 
roles.id,
roles.name,
roles.abbreviation,
roles.active,
(CASE WHEN roles.updated_at IS NULL
    THEN roles.created_at
    ELSE roles.updated_at
    END) as last_Modified,
(CASE WHEN user_roles_count.number_of_users IS NULL
    THEN 0
    ELSE user_roles_count.number_of_users
    END) as number_of_users
FROM roles
    LEFT JOIN (SELECT user_roles.role_id, COUNT(user_roles.user_id) as number_of_users
        FROM user_roles GROUP BY user_roles.role_id
    ) as user_roles_count ON roles.id = user_roles_count.role_id ORDER BY roles.id ASC, last_Modified DESC;

初始编写的基础版本查询未适配动态可选字段逻辑,代码如下:

def get_roles(session, offset, limit):
    status_1 = f"""(CASE WHEN roles.updated_at IS NULL
        THEN roles.created_at
        ELSE roles.updated_at
        END) as last_Modified"""
    count_Query = session.query(UserRoles.role_id, func.count(
        UserRoles.user_id).label("number_of_users")).group_by(UserRoles.role_id).subquery()
    status_2 = f"""(CASE WHEN {count_Query.c.role_id} IS NULL
    THEN 0
    ELSE {count_Query.c.role_id}
    END) as number_of_users"""
    statement_result = session.query(
        Roles.id,
        Roles.name,
        Roles.abbreviation,
        Roles.active,
        text(status_1),
        text (status_2)
    ).join(count_Query, count_Query.c.role_id == Roles.id,
    isouter=True).order_by(asc(Roles.id)).slice(offset, limit).all()
    columns = ["id", "name", "abbreviation",
                "active", "updatedAt", "numberOfUsers"]
    get_products = struct_response(statement_result, columns)
    return get_products
实现方案

排查确认原代码存在分页参数offset、limit的逻辑错误,修复后基于SQLAlchemy的链式调用特性完成动态逻辑适配:先构造不含动态条件的基础查询,再通过独立if判断校验入参,存在对应可选字段时追加对应的过滤、排序条件,最后统一执行分页查询。
最终可用代码如下:

def get_roles(session, offset, limit, event):
    status_1 = f"""(CASE WHEN roles.updated_at IS NULL
        THEN roles.created_at
        ELSE roles.updated_at
        END) as last_Modified"""

    count_Query = session.query(UserRoles.role_id, func.count(
        UserRoles.user_id).label("number_of_users")).group_by(UserRoles.role_id).subquery()

    status_2 = f"""(CASE WHEN {count_Query.c.role_id} IS NULL
    THEN 0
    ELSE {count_Query.c.role_id}
    END) as number_of_users"""

    # 构造基础查询
    query = session.query(
        Roles.id,
        Roles.name,
        Roles.abbreviation,
        Roles.active,
        text(status_1),
        text(status_2)
    ).join(count_Query, count_Query.c.role_id == Roles.id,
        isouter=True).order_by(asc(Roles.id))

    # 动态追加名称模糊搜索条件
    if "name" in event:
        name = event["name"]
        search = "%{}%".format(name)
        query = query.filter(Roles.name.like(search))
    # 动态追加状态过滤条件
    if "status" in event:
        query = query.filter(Roles.active == event["status"])
    # 动态追加排序规则
    if "newest_first" in event:
        if event["newest_first"] == True:
            query = query.order_by(asc(Roles.created_at))
        else:
            query = query.order_by(desc(Roles.created_at))

    # 执行分页查询
    query_result = query.slice(offset, limit).all()

    columns = ["id", "name", "abbreviation",
            "active", "updatedAt", "numberOfUsers"]
    get_roles = struct_response(query_result, columns)

    return get_roles

内容的提问来源于stack exchange,提问作者Juan David Polo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 20:45:36