Flask项目MySQL多列过滤失效求助及SQLAlchemy方案咨询
问题修复与优化方案
一、修复当前flask_mysqldb的多条件过滤问题
1. 前端index.html脚本修复
原脚本存在监听事件绑定错误、DOM选择器错误、数据更新逻辑冗余三个核心问题,修改后代码如下:
<script> $(document).ready(function(){ // 绑定两个下拉框的change事件 $('#search_filter_player1, #search_filter_type').change(function(){ $('#hidden_value_player1').val($('#search_filter_player1').val()); $('#hidden_value_type').val($('#search_filter_type').val()); load_data(); }); load_data(); function load_data() { var action = 'fetch_data'; var player_id = $('#hidden_value_player1').val(); var type = $('#hidden_value_type').val(); $.ajax({ url:"/fetchrecords", method:"POST", data:{action:action, player_id:player_id, type:type}, success:function(data) { // 直接替换表格tbody内容 $('table tbody').html(data.htmlresponse); } }) } }); </script>
同时调整表格tbody标签,确保选择器能正确命中:
<tbody class="load_data"></tbody>
另外移除HTML选项中多余的';字符(如<option value="">Player 1</option>';改为<option value="">Player 1</option>),避免页面渲染异常。
2. 后端app.py逻辑修复
原SQL强制用AND连接两个条件,任一过滤条件为空时会导致无数据返回,需动态构建查询条件:
@app.route("/fetchrecords",methods=["POST","GET"]) def fetchrecords(): cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor) if request.method == 'POST': player_id = request.form.get('player_id', '') type_val = request.form.get('type', '') # 动态构建SQL语句与参数列表 sql = "SELECT * FROM actions" params = [] conditions = [] if player_id: conditions.append("player_id = %s") params.append(player_id) if type_val: conditions.append("type = %s") params.append(type_val) if conditions: sql += " WHERE " + " AND ".join(conditions) cur.execute(sql, params) datalist = cur.fetchall() return jsonify({'htmlresponse': render_template('response.html', datalist=datalist)})
注意:将变量名type改为type_val,避免与Python内置关键字冲突。
二、使用SQLAlchemy实现多条件过滤的更优方案
SQLAlchemy提供更安全简洁的ORM操作,避免手动拼接SQL的风险,以下是完整实现:
1. 安装依赖
pip install flask-sqlalchemy
2. 修改app.py为SQLAlchemy版本
from flask import Flask, render_template, jsonify, request from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # 替换为你的数据库实际连接信息 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://用户名:密码@主机地址/数据库名' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) # 定义Actions模型,对应数据库actions表结构 class Actions(db.Model): id = db.Column(db.Integer, primary_key=True) edition_id = db.Column(db.Integer) game_id = db.Column(db.Integer) player_id = db.Column(db.String(50)) type = db.Column(db.String(10)) @app.route('/') def index(): # ORM方式查询去重的player_id player_ids = db.session.query(Actions.player_id).distinct().all() # 转换为模板适配的字典列表 player_id_list = [{'player_id': p[0]} for p in player_ids] return render_template('index.html', player_id=player_id_list) @app.route("/fetchrecords",methods=["POST","GET"]) def fetchrecords(): if request.method == 'POST': player_id = request.form.get('player_id', '') type_val = request.form.get('type', '') # 动态构建查询过滤器 query = Actions.query if player_id: query = query.filter(Actions.player_id == player_id) if type_val: query = query.filter(Actions.type == type_val) datalist = query.all() return jsonify({'htmlresponse': render_template('response.html', datalist=datalist)}) if __name__ == "__main__": # 初始化数据库表(仅首次运行需要) with app.app_context(): db.create_all() app.run(debug=True)
3. 模板文件调整
response.html无需修改,SQLAlchemy模型对象支持直接通过属性访问(如row.id、row.player_id),与原字典格式完全兼容。
核心优势对比
- SQLAlchemy版本:无需手动拼接SQL,彻底避免SQL注入风险;代码可读性更高;支持复杂查询(关联、排序、分页);数据库迁移更便捷。
- flask_mysqldb版本:适合熟悉原生SQL的场景,但需手动处理SQL拼接与参数绑定,出错概率更高。
内容的提问来源于stack exchange,提问作者cracaud
相关产品推荐
相关产品推荐

