如何将SQLite触发器抛出的错误信息在Python Flask应用中展示?
解决Flask中捕获SQLite触发器错误并转为Flash消息的方案
1. 确保触发器抛出可识别的错误信息
首先确认你的SQLite触发器明确抛出包含特征关键词的错误,这样后续能精准判断:
CREATE TRIGGER avoid_duplicate_Patient_IDs BEFORE INSERT ON pt_register FOR EACH ROW WHEN EXISTS (SELECT 1 FROM pt_register WHERE Patient_ID = NEW.Patient_ID) BEGIN SELECT RAISE(ABORT, 'Patient ID duplicate'); END;
2. 在Flask视图中捕获异常并触发Flash消息
在处理表单提交的视图函数里,捕获SQLAlchemy抛出的IntegrityError(触发器的ABORT操作会触发该异常),提取原生错误信息后匹配关键词,再发送自定义提示:
from flask import flash, redirect, url_for, render_template from sqlalchemy.exc import IntegrityError # 导入你的app、db、模型、表单类 @app.route('/patient/register', methods=['GET', 'POST']) def pt_register(): form = Pt_RegisterForm() if form.validate_on_submit(): new_pt = pt_register( Patient_ID=form.Patient_ID.data, # 其他字段赋值 ) try: db.session.add(new_pt) db.session.commit() flash('注册成功', 'success') return redirect(url_for('pt_list')) except IntegrityError as e: db.session.rollback() # 必须回滚失效的数据库会话 # 提取SQLite原生错误信息 raw_error = str(e.orig) if 'Patient ID duplicate' in raw_error: flash('Patient ID已注册/重复录入', 'danger') else: flash('数据库完整性异常,请检查输入', 'danger') except Exception as e: db.session.rollback() flash(f'注册失败:{str(e)}', 'danger') return render_template('pt_register.html', form=form)
3. 确保Jinja2模板正确渲染Flash消息
在模板中添加Flash消息的渲染逻辑,确保提示能显示给用户:
<!-- 在模板顶部或表单上方添加 --> {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, msg in messages %} <div class="alert alert-{{ category }} alert-dismissible fade show" role="alert"> {{ msg }} <button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div> {% endfor %} {% endif %} {% endwith %} <!-- 表单代码保持原有结构 --> <form method="POST"> {{ form.hidden_tag() }} <div class="mb-3"> {{ form.Patient_ID.label(class="form-label") }} {{ form.Patient_ID(class="form-control") }} {% for err in form.Patient_ID.errors %} <small class="text-danger">{{ err }}</small> {% endfor %} </div> <!-- 其他表单字段 --> <button type="submit" class="btn btn-primary">提交注册</button> </form>
关键注意事项
- 不要给模型的
Patient_ID字段设置unique=True:否则SQLAlchemy会在提交前先做唯一性检查,触发器的逻辑会被覆盖,且抛出的异常信息会不同。 - 必须执行
db.session.rollback():异常发生后数据库会话处于失效状态,不回滚会导致后续所有数据库操作失败。 - 触发器错误信息要固定:确保特征关键词唯一,避免误判其他类型的完整性错误。
内容的提问来源于stack exchange,提问作者Saul Tamez
相关产品推荐
相关产品推荐

