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

SQL查询执行无报错,调用值时出现'lgi'未定义错误求助

排查Jinja2 UndefinedError: 'lgi' is undefined问题

看起来你遇到的问题出在SQL查询返回结果的结构和Jinja2模板的引用方式不匹配上,我来一步步帮你拆解:

问题根源

你的SQL查询里虽然写了lgi.staff_id,但默认情况下数据库连接(比如SQLAlchemy的conn.execute())返回的是无命名空间的行对象/元组——也就是说,返回的结果里并没有一个叫lgi的属性或键,只有单独的staff_id字段(而且你同时选了s.staff_id和lgi.staff_id,这俩字段名重复,还会导致后者覆盖前者)。

当Jinja2模板里尝试写{{ lgi.staff_id }}这类代码时,模板引擎找不到名为lgi的变量,自然就抛出UndefinedError了。

具体解决方案

方案一:给SQL字段加别名,返回字典格式结果

先修改SQL查询给重复字段加别名,同时把结果转成字典(方便按键访问):

def search_staff():
    sql_staff = """
        SELECT 
            s.forename, 
            s.surname, 
            s.brc, 
            s.oou_id, 
            s.staff_id AS staff_id_main,  -- 给主表staff_id加别名
            s.status, 
            lgi.staff_id AS staff_id_lgi  -- 给关联表staff_id加别名
        FROM staff s 
        JOIN local_grant_investigators as lgi ON s.staff_id = lgi.staff_id 
        GROUP BY s.forename, s.surname, s.brc, s.oou_id, s.staff_id, s.status, lgi.staff_id;
    """
    # 将查询结果转为字典列表,让字段名成为可访问的键
    r_s = [dict(row) for row in conn.execute(text(sql_staff))]
    return r_s  # 别忘了返回结果,否则模板拿不到数据

然后在Jinja2模板里直接用别名访问字段:

{% if staff %}
<table>
    <thead>
        <th>Forename</th>
        <th>Surname</th>
        <th>LGI Staff ID</th>
    </thead>
    <tbody>
        {% for item in staff %}
        <tr>
            <td>{{ item.forename }}</td>
            <td>{{ item.surname }}</td>
            <td>{{ item.staff_id_lgi }}</td>  <!-- 用别名访问关联表的staff_id -->
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endif %}

方案二:使用命名元组(SQLAlchemy场景)

如果你用的是SQLAlchemy,也可以用命名元组让结果更直观:

from sqlalchemy import text
from collections import namedtuple

def search_staff():
    sql_staff = """
        SELECT 
            s.forename, 
            s.surname, 
            s.brc, 
            s.oou_id, 
            s.staff_id, 
            s.status, 
            lgi.staff_id AS lgi_staff_id
        FROM staff s 
        JOIN local_grant_investigators as lgi ON s.staff_id = lgi.staff_id 
        GROUP BY s.forename, s.surname, s.brc, s.oou_id, s.staff_id, s.status, lgi.staff_id;
    """
    result = conn.execute(text(sql_staff))
    # 创建对应字段的命名元组类
    StaffRow = namedtuple('StaffRow', result.keys())
    r_s = [StaffRow(*row) for row in result]
    return r_s

模板里同样用别名{{ item.lgi_staff_id }}访问即可。

额外提醒

  • 因为JOIN条件是s.staff_id = lgi.staff_id,这两个字段的值是完全相等的,其实没必要同时查询,选一个就能满足需求,还能避免字段名重复的问题。
  • 一定要确保search_staff()函数返回了查询结果,如果之前漏写了return r_s,模板里的staff变量会是空值,也可能引发异常。

内容的提问来源于stack exchange,提问作者Clives-online

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:43:33