You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

提交表单至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)就能解决问题。另外我还帮你优化了几个冗余/不严谨的地方:

  1. 删掉了手动写的__init__方法——SQLAlchemy的db.Model已经自动实现了属性初始化逻辑,这些代码完全多余。
  2. 把两次db.session.commit()合并成一次,减少数据库操作的开销。
  3. 补全了__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)

额外小建议(可选)

如果想在页面上直观看到已添加的书籍和出版社,可以修改路由和模板:

  1. 更新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)
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:08:28