使用Flask、Jinja2、Python和SQLAlchemy展示数据库信息失败求助
问题排查与解决方案
核心问题分析
- 主键重复插入异常:每次访问
/books的GET请求都会执行插入id=1的图书记录,第二次访问时主键冲突,抛出数据库异常,导致页面无法正常返回数据。 - 日期类型不匹配:
publish_year字段定义为Date类型,但你传入的是整数1851,不符合SQLAlchemy的Date类型要求,会导致插入失败。 - 图片存储逻辑错误:你在
image字段中存储了带模板语法的HTML字符串,这既不安全,也无法在模板中正确解析渲染。
修复后的代码示例
1. 修改views.py
from datetime import date # 导入datetime的date类 views = Blueprint('views', __name__, template_folder="templates") @views.route('/') @login_required def home(): return render_template("home.html") @views.route('/books', methods=['GET','POST']) @login_required def books(): if request.method == 'GET': # 先检查是否已存在id=1的记录,避免重复插入 existing_book = Book.query.get(1) if not existing_book: # publish_year使用date对象匹配字段类型 new_book = Book( id=1, title='Moby-Dick, or The Whale', authors_name='Herman Melville', publisher='Harper & Brothers', page_count=378, publish_year=date(1851, 1, 1), # 改为具体日期的date对象 image='mobydick.jpg' # 只存图片文件名 ) db.session.add(new_book) db.session.commit() # 查询所有图书 books = Book.query.all() return render_template("books.html", books=books)
2. 修改books.html(添加图片展示)
{% extends "base.html" %} {% block title %}Books{% endblock %} {% block content %} <h1>Books!</h1> <ul> {% for book in books %} <li> <h3>{{ book.title }}</h3> <p>作者:{{ book.authors_name }}</p> <!-- 使用url_for生成静态图片的正确URL --> <img src="{{ url_for('static', filename='images/' + book.image) }}" alt="{{ book.title }}封面" width="100"> </li> {% endfor %} </ul> {% endblock %}
额外注意事项
- 确保
static/images目录存在,且mobydick.jpg已放在该目录下。 - 若要批量插入数据,建议使用命令行脚本或Flask shell,不要在路由中每次请求都执行插入逻辑,避免性能问题和异常。
- 后续可以考虑移除手动指定
id的逻辑,让数据库自动生成主键(模型中id字段默认就是自增主键,无需手动赋值)。
内容的提问来源于stack exchange,提问作者rupertpurple
相关产品推荐
相关产品推荐

