Flask应用使用Peewee读数据库报no such table: product错误
问题根因
这个报错的核心原因是数据库初始化、建表逻辑的执行时机不对:
- 你直接在Python文件里调用search函数时,脚本从上到下顺序执行,写在前面的数据库连接、建表代码会正常跑完,表存在所以查询正常
- 启动Flask服务时,如果你把
db.connect()、db.create_tables([Product])这类逻辑写在了if __name__ == "__main__":代码块里,Flask开发模式的重载器导入脚本时不会执行这个块里的代码,实际处理请求时连接的是没有任何表的空数据库,自然会报找不到product表的错误。
修复方案
- 第一步:把数据库连接、模型定义、建表逻辑移到Flask app初始化之前,不要放在
__main__判断块里,参考正确代码结构:
from flask import Flask, request, redirect, url_for, render_template from peewee import SqliteDatabase, Model, CharField, IntegerField, FloatField # 初始化数据库连接 db = SqliteDatabase('product.db') # 定义数据模型 class Product(Model): name = CharField() price = FloatField() description = CharField() quant = IntegerField() class Meta: database = db # 服务启动前完成建表(开发阶段直接调用即可,生产环境建议替换为单独的数据库迁移脚本) db.connect() db.create_tables([Product]) # 初始化Flask应用 app = Flask(__name__) # 原有业务逻辑 def search(term): items = Product.select().where(Product.name == term) my_list = [] for item in items: p_str = "Product: {}, Price: {}, Description: {}, Quantity in stock: {}".format(item.name,item.price, item.description, item.quant) my_list.append(p_str) return my_list @app.route("/", methods=["GET", "POST"]) def index(name="Index"): if request.method == "POST": product = request.form["item"] my_item = search(str(product)) return redirect(url_for("store", item=my_item)) return render_template("index.html", title=name) @app.route("/store") def store(name="Store"): return render_template("store.html", title=name, items=request.args.getlist("item")) if __name__ == "__main__": app.run(debug=True)
- 第二步:如果调整代码位置后仍然报错,先删除本地目录下旧的
.db后缀数据库文件,再重新启动服务,避免旧的空库文件残留导致异常。
额外提示:你当前把查询结果列表通过URL参数传递的写法存在缺陷,URL参数仅支持字符串传输,列表会被强制转义,后续可以改用session或者服务端缓存传递查询结果,避免数据格式异常。
内容的提问来源于stack exchange,提问作者Samuel Lino
相关产品推荐
相关产品推荐

