Four Hours Wasted Over a Parenthesis! (Python + SQLAlchemy)
drks — Tue, 2009-06-09 16:58
I've spent the last half day banging my head against the wall wondering 'WTF!?'. I'm working on a semi-complex pluggable framework type application. As part of this app, I have a shared database handler. So of course, I thought there was something underlying with SQLA that was limiting me from being able to accomplish the task as I sawr it in my head. I tried so many combination of mapping classes to database tables, and no matter what I would get the following exception:
raise exc.UnmappedInstanceError(instance) sqlalchemy.orm.exc.UnmappedInstanceError: Class '__builtin__.type' is not mapped; was a class (__main__.User) supplied where an instance was required?
Everything seemed to be in place, even printing out 'class_mapper(User)' spit out the right mapping, as expected... but just after that trying to save/commit to the database would raise this ugly exception.
Don't get me wrong... If you really look at it, it is a very straight forward exception telling me that I passed a class where an instance was expected. To see where I went wrong, I wrote this quick example to trigger the issue:
idiot_check.py:
from sqlalchemy import * from sqlalchemy.orm import sessionmaker, mapper, scoped_session db = create_engine('sqlite:///idiot_check.db') db.echo = False metadata = MetaData(db) session = scoped_session(sessionmaker(bind=db)) class User(object): pass users_table = Table('users', metadata, Column('user_id', Integer, primary_key=True), Column('name', String(40)), Column('age', Integer), Column('password', String), ) users_mapper = mapper(User, users_table) if not db.engine.has_table('users'): db.create(users_table) u = User u.name = 'bill' u.age = '21' session.add(u) session.commit()
Many a pythonista will immediately catch my fault, but lets just assume that there are other people able to screw up as I did. Here is the output of this example again:
$ python idiot_check.py
Traceback (most recent call last):
File "idiot_check.py", line 24, in <module>
session.add(u)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.5.3-py2.6.egg/sqlalchemy/orm/scoping.py", line 121, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.5.3-py2.6.egg/sqlalchemy/orm/session.py", line 1090, in add
state = _state_for_unknown_persistence_instance(instance)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.5.3-py2.6.egg/sqlalchemy/orm/session.py", line 1566, in _state_for_unknown_persistence_instance
raise exc.UnmappedInstanceError(instance)
sqlalchemy.orm.exc.UnmappedInstanceError: Class '__builtin__.type' is not mapped; was a class (__main__.User) supplied where an instance was required?In my troubleshooting efforts, this exception kept leading me toward the section of code where I was mapping the class to the database table. Over and over I focussed in the wrong place.
The following was actually my problem:
u = User
This obviously (laugh... obviously) needs to be an instance and should be:
u = User()
With the idiot fix in place, everything is now kosher:
$ python idiot_check.py $
No exception, and the code worked:
$ sqlite3 idiot_check.db SQLite version 3.6.10 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> select * from users; 1|bill|21|
Lets say it together now:
FAIL!
RSS Feed
Thank you!
Andrea Spadaccini (not verified) — Tue, 2009-11-24 16:22Thank you for your post, that inspired me the solution for a similar problem.
I got an UnmappedInstanceException too, but I was more stupid than you: I didn't call .first() on an Elixir query.
Post new comment