Flask框架下MySQL无法向customer表插入数据问题求助
Flask路由插入MySQL数据不生效排查方案
核心故障点按出现概率从高到低排列:
- 无异常捕获机制,SQL执行报错后直接中断,无法走到
commit()逻辑
现有代码未做任何错误捕获,只要SQL执行触发异常(主键冲突、语法错误、字段约束不满足),代码会直接抛出错误终止运行,根本不会执行后续的事务提交语句,数据自然无法落库。最常见的触发报错场景:- 用f-string拼接用户输入的name值时,若name包含单引号(如
O'neal),拼接出的SQL会直接出现语法错误 - 若customer表
id字段设置为自增主键,手动传入的id与已有数据重复时会触发主键冲突 - 表单提交的id/name为空时,会触发表字段的非空约束报错
- 用f-string拼接用户输入的name值时,若name包含单引号(如
- f-string拼接SQL的写法不符合数据库驱动规范
所有Python操作MySQL的驱动都要求使用参数化查询传值,自行拼接SQL不仅有SQL注入风险,还容易出现特殊字符未转义、类型不匹配的问题,直接导致SQL执行失败。 - 数据库连接、游标作用域异常
如果cursor定义为全局变量、不是每次请求从有效db_conn实例创建的,会出现游标绑定的连接已失效、执行记录与当前连接不匹配的问题,就算执行到commit语句也无法完成事务提交。 - 前端表单属性写法不规范
现有form标签的action属性值未加双引号,特殊场景下会出现地址解析错误,请求无法打到正确路由。
修正后的可运行代码
后端路由部分:
@app.route("/add", methods=["GET", "POST"]) def add_customer(): """create new customer""" if request.method == "POST": # 基础参数校验 cust_id = request.form.get("id", "").strip() cust_name = request.form.get("name", "").strip() if not cust_id or not cust_name: flash("ID和姓名不能为空") return redirect(url_for("add_customer")) # 参数化查询,禁止直接拼接SQL sql = "INSERT INTO customer(id, name) VALUES (%s, %s)" try: # 每次请求从有效连接创建游标,不使用全局cursor cursor = db_conn.cursor() cursor.execute(sql, (cust_id, cust_name)) db_conn.commit() cursor.close() flash("New customer created!") except Exception as e: # 执行失败先回滚事务,打印错误信息方便排查 db_conn.rollback() flash(f"创建失败:{str(e)}") return redirect(url_for("home")) return render_template("addcustomer.html")
前端表单模板(修正action属性写法,增加前端必填校验):
<!doctype html> <title>Add customer</title> <form action="{{url_for('add_customer')}}" method="POST"> <p>Name:</p> <input type="text" size="50" name="name" required> <p>ID number:</p> <input type="number" size="50" name="id" required> <input type="submit" value ="Create"> <a href = "{{url_for('home')}}"><button type="button">Cancel</button></a> </form>
额外优化提示:如果customer表的id字段是自增主键,完全不需要在INSERT语句中传入id,数据库会自动生成唯一值,可以彻底避免主键冲突问题。这种场景下把SQL调整为
INSERT INTO customer(name) VALUES (%s),同时移除前端的id输入框即可。
内容的提问来源于stack exchange,提问作者Raskolnikov
相关产品推荐
相关产品推荐

