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
相关产品推荐
相关产品推荐

