提交表单至SQLAlchemy遇UnmappedInstanceError错误求助
解决sqlalchemy.orm.exc.UnmappedInstanceError错误
这个错误的根源非常直观——你在把Publisher对象添加到数据库会话时,不小心传了类本身,而不是你已经创建好的类实例。
看看你home路由里的这段代码:
pub = Publisher(name=request.form.get('pub_name')) db.session.add(Publisher) # 这里犯了关键错误! db.session.commit()
你已经正确创建了pub这个Publisher实例,但却把Publisher类(不是实例)传给了db.session.add()。SQLAlchemy需要的是映射好的模型实例,而不是类本身,所以它抛出了这个"未映射实例"的错误。
修正后的完整代码
只需要把db.session.add(Publisher)改成db.session.add(pub)就能解决问题。另外我还帮你优化了几个冗余/不严谨的地方:
- 删掉了手动写的
__init__方法——SQLAlchemy的db.Model已经自动实现了属性初始化逻辑,这些代码完全多余。 - 把两次
db.session.commit()合并成一次,减少数据库操作的开销。 - 补全了
__repr__方法里缺失的右尖括号,让输出格式更规范。
import os from flask import Flask, render_template, request from flask_sqlalchemy import SQLAlchemy project_dir = os.path.dirname(os.path.abspath(__file__)) database_file = "sqlite:///{}".format(os.path.join(project_dir,"bookdatabase.db")) app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = database_file db = SQLAlchemy(app) class Book(db.Model): title = db.Column(db.String(80), unique=True, nullable=False, primary_key=True) def __repr__(self): return "<Title: {}>".format(self.title) class Publisher(db.Model): name = db.Column(db.String(80), unique=True, nullable=False, primary_key=True) def __repr__(self): return "<Name: {}>".format(self.name) @app.route("/", methods=["GET","POST"]) def home(): if request.form: book = Book(title=request.form.get('title')) pub = Publisher(name=request.form.get('pub_name')) db.session.add(book) db.session.add(pub) db.session.commit() return render_template('home.html') if __name__=="__main__": app.run(debug=True)
额外小建议(可选)
如果想在页面上直观看到已添加的书籍和出版社,可以修改路由和模板:
- 更新
home路由,把查询到的数据传给模板:
@app.route("/", methods=["GET","POST"]) def home(): if request.form: book = Book(title=request.form.get('title')) pub = Publisher(name=request.form.get('pub_name')) db.session.add(book) db.session.add(pub) db.session.commit() books = Book.query.all() publishers = Publisher.query.all() return render_template('home.html', books=books, publishers=publishers)
- 在
home.html里添加显示逻辑:
<h3>已添加的书籍</h3> <ul> {% for book in books %} <li>{{ book.title }}</li> {% endfor %} </ul> <h3>已添加的出版社</h3> <ul> {% for pub in publishers %} <li>{{ pub.name }}</li> {% endfor %} </ul>
内容的提问来源于stack exchange,提问作者Houy Narun
相关产品推荐
相关产品推荐

