Flask中如何处理数据库查询返回的元组类型结果以实现页面展示?
Flask中如何处理数据库查询返回的元组类型结果以实现页面展示?
看起来你卡在数据库查询结果传到Flask模板展示的问题上了,我来帮你理清楚问题出在哪以及怎么解决~
首先得搞懂你遇到的核心问题:cursor.fetchall()返回的是元组组成的列表——每一行查询结果是一个元组,所有行放在一个列表里。你直接把这个结果赋值给unit传到模板,再加上你参数里的unit和返回结果的unit重名,很容易在模板处理时把整个元组当成单个值去转换,才会报“int() argument must be a string... not 'tuple'”的错。
下面给你几个实用的解决方案:
方案一:直接在模板里正确遍历元组列表
先把路由里的变量名改清晰,避免和查询参数重名(这是很容易踩的小坑!),然后在模板里用Jinja2循环遍历:
路由代码修改示例
conn = sql.connect('./database.db') cursor = conn.cursor() # 把查询参数改名为unit_param,和返回结果区分开 cursor.execute('SELECT year, unit, facilities, workforce, vehicles FROM units WHERE unit = ?', (unit_param,)) # 返回结果改名为unit_records,更直观 unit_records = cursor.fetchall() conn.close() # 把records传到模板 return render_template('analysis.html', unit_records=unit_records)
模板(analysis.html)遍历代码
在模板里用循环逐个取出元组里的字段,通过索引访问每个位置的值:
<table> <tr> <th>年份</th> <th>单位</th> <th>设施</th> <th>员工数</th> <th>车辆数</th> </tr> {% for record in unit_records %} <tr> <td>{{ record[0] }}</td> <td>{{ record[1] }}</td> <td>{{ record[2] }}</td> <td>{{ record[3] }}</td> <td>{{ record[4] }}</td> </tr> {% endfor %} </table>
方案二:把元组转成字典列表,模板用字段名更直观
如果觉得用索引记起来麻烦,可以把查询结果转成字典的列表,每个字典的key就是数据库字段名,这样模板里可以直接用字段名取值,更清晰:
路由代码修改示例
conn = sql.connect('./database.db') cursor = conn.cursor() cursor.execute('SELECT year, unit, facilities, workforce, vehicles FROM units WHERE unit = ?', (unit_param,)) # 获取查询的字段名 column_names = [desc[0] for desc in cursor.description] # 把每个元组行转成字典,和字段名对应 unit_records = [dict(zip(column_names, row)) for row in cursor.fetchall()] conn.close() return render_template('analysis.html', unit_records=unit_records)
模板(analysis.html)遍历代码
这时候就可以直接用字段名取值,可读性强很多:
<table> <tr> <th>年份</th> <th>单位</th> <th>设施</th> <th>员工数</th> <th>车辆数</th> </tr> {% for record in unit_records %} <tr> <td>{{ record.year }}</td> <td>{{ record.unit }}</td> <td>{{ record.facilities }}</td> <td>{{ record.workforce }}</td> <td>{{ record.vehicles }}</td> </tr> {% endfor %} </table>
为什么你之前的方法没起作用?
- 转成列表
unit = list(unit):其实fetchall()返回的本身就是列表,里面的元素是元组,所以转列表之后结构完全没变,问题自然没解决。 - 用
json.dumps()转JSON字符串:这时候你传到模板的是一个字符串,模板如果还是按列表去遍历,就会把字符串的每个字符当成元素,比如第一个字符是[,去转int就会报“invalid literal for int() with base 10: '['”的错,这显然不是正确的处理方式。
最后再提醒一句:一定要把查询参数和返回结果的变量名区分开,重名很容易导致各种莫名其妙的错误!
内容来源于stack exchange
相关产品推荐
相关产品推荐

