Python 烧瓶中的 sqlalchemy.orm.exc.UnmappedInstanceError

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21196824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 22:16:27  来源:igfitidea点击:

sqlalchemy.orm.exc.UnmappedInstanceError in flask

pythonsqlalchemyflaskflask-sqlalchemy

提问by user2986242

I have been reading the SQLAlchemy docs, but I don't understand them. The error (UnmappedInstanceError) says something isn't mapped. What isn't mapped? I really don't get sqlalchemy and I want to go back to using naked sqlite, but so many people recommend this, so I thought I should learn it. Here is the traceback:

我一直在阅读 SQLAlchemy 文档,但我不理解它们。错误 (UnmappedInstanceError) 表示未映射某些内容。什么没有映射?我真的不明白 sqlalchemy,我想回去使用裸 SQLite,但这么多人推荐这个,所以我想我应该学习它。这是回溯:

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)

File "C:\Users\Me\repos\mandj2\app\views.py", line 170, in add_manentry
db.session.add(q)

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\sqlalchemy\orm\scoping.py", line 149, in do
return getattr(self.registry(), name)(*args, **kwargs)

File "C:\Users\Me\repos\mandj\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1452, in add
raise exc.UnmappedInstanceError(instance)

UnmappedInstanceError: Class '__builtin__.unicode' is not mapped

Here is the applicable code:

这是适用的代码:

@app.route('/addm', methods=['POST'])
def add_mentry():
    if not session.get('logged_in'):
        abort(401)
    form = MForm(request.form)
    filename = ""
    if request.method == 'POST':
        cover = request.files['cover']
        if cover and allowed_file(cover.filename):
            filename = secure_filename(cover.filename)
            cover = cover.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))

    q = request.form['name']
    # do for 12 more fields
    db.session.add(q)
    db.session.commit()
    flash('New entry was successfully posted')
    return redirect(url_for('moutput'))

采纳答案by Mark Hildreth

q = request.form['name']
# do for 12 more fields
db.session.add(q)

request.form['name']will return a unicode value. Then, you do...

request.form['name']将返回一个 unicode 值。那么,你做...

db.session.add(q)

The goal of the session is to keep track of Entities (Python objects), not individual unicode values as you seem to be trying to do it (See herefor more on what the session does). Thus, you should be adding objects that have a mapping (such as a Userobject as shown in the "Mapping" sectionof the ORM tutorial), but you're actually passing a simple unicode value

会话的目标是跟踪实体(Python 对象),而不是像您试图这样做的单个 unicode 值(有关会话功能的更多信息,请参见此处)。因此,您应该添加具有映射的User对象(例如ORM 教程“映射”部分中所示的对象),但实际上传递的是一个简单的 unicode 值

What you're using is just one part of SQLAlchemy: the ORM (Object-Relational Mapper). The ORM will try to do things like allow you to create a new python object and have the SQL automatically generaeted by "adding" the object to the session..

您使用的只是 SQLAlchemy 的一部分:ORM(对象关系映射器)。ORM 会尝试做一些事情,比如允许你创建一个新的 python 对象,并通过将对象“添加”到会话中来自动生成 SQL。

a = MyEntity()
session.add(a)
session.commit() # Generates SQL to do an insert for the table that MyEntity is for

Keep in mind that you can use SQLAlchemy without using the ORM functionality. You could just do db.execute('INSERT...', val1, val2)to replace your already "naked" SQL. SQLAlchemy will provide you connection pooling, etc (although if you're using SQLite, you probably don't care about connection pooling).

请记住,您可以在不使用 ORM 功能的情况下使用 SQLAlchemy。你可以做db.execute('INSERT...', val1, val2)来替换你已经“裸”的 SQL。SQLAlchemy 将为您提供连接池等(尽管如果您使用 SQLite,您可能不关心连接池)。

If you want to understand Flask-SQLAlchemy, I would first recommend understanding how SQLAlchemy works (especially the ORM side) by trying it out using simple scripts (as shown in the tutorials. Then you'll understand how Flask-SQLAlchemy would work with it.

如果您想了解 Flask-SQLAlchemy,我首先建议您通过使用简单的脚本(如教程中所示)尝试了解 SQLAlchemy 的工作原理(尤其是 ORM 方面)。然后您将了解 Flask-SQLAlchemy 将如何使用它.

回答by Devy

When you are adding a non-model-object into the session, you will be getting UnmappedInstanceError.

当您将非模型对象添加到会话中时,您将获得UnmappedInstanceError.

In your case, qwas probably an unicode string, not a model object. (It appears that you are using Python 2.x because in Python 3.x, it will say str), this was the line of the root cause for UnmappedInstanceError: Class '__builtin__.unicode' is not mapped:

在您的情况下,q可能是一个 unicode 字符串,而不是模型对象。(看来您正在使用 Python 2.x,因为在 Python 3.x 中,它会说 str),这是根本原因的行UnmappedInstanceError: Class '__builtin__.unicode' is not mapped

  File "C:\Users\Me\repos\mandj2\app\views.py", line 170, in add_manentry
  db.session.add(q)

回答by Andy

If you are changing database see: You have to address to what item in the object you want to change. See below:

如果您正在更改数据库,请参阅:您必须解决要更改的对象中的项目。见下文:

client = session.query(Clients).filter_by(id=client_id).one()
if request.method == 'POST':
    new_name = request.form['form_name']
    client.name = new_name
    session.add(client)
    session.commit()

As you can see in the 'client' object, we have "name" among other info inside the object. We want to directly change 'name' only, therefore you need to address to it. (client.name)

正如您在 'client' 对象中看到的,我们在对象内的其他信息中包含“名称”。我们只想直接更改“名称”,因此您需要对其进行寻址。(客户名称)



If you are adding new thing to database: Here when you add a new value to the database with orm, you need to specify the item in the object that is receiving the data. in this case (Client.name)

如果要向数据库添加新事物:这里当您使用orm向数据库添加新值时,需要指定正在接收数据的对象中的项目。在这种情况下(Client.name)

    if request.method == 'POST':
        new_name = request.form['form_name']
        name = Clients(name=new_name)
        session.add(name)
        session.commit()

Hope that helps.

希望有帮助。