Default class for SQLAlchemy single table inheritance

Posted by eclaird on Stack Overflow See other posts from Stack Overflow or by eclaird
Published on 2011-01-04T08:48:15Z Indexed on 2011/01/04 8:54 UTC
Read the original article Hit count: 552

I've set up a single table inheritance, but I need a "default" class to use when an unknown polymorphic identity is encountered. The database is not in my control and so the data can be pretty much anything.

A working example setup:

import sqlalchemy as sa
from sqlalchemy import orm

engine = sa.create_engine('sqlite://')
metadata = sa.MetaData(bind=engine)

table = sa.Table('example_types', metadata,
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('type', sa.Integer),
    )

metadata.create_all()

class BaseType(object):
    pass

class TypeA(BaseType):
    pass

class TypeB(BaseType):
    pass


base_mapper = orm.mapper(BaseType, table,
    polymorphic_on=table.c.type,
    polymorphic_identity=None,
    )
orm.mapper(TypeA,
    inherits=base_mapper,
    polymorphic_identity='A',
    )
orm.mapper(TypeB,
    inherits=base_mapper,
    polymorphic_identity='B',
    )

Session = orm.sessionmaker(autocommit=False, autoflush=False)
session = Session()

Now, if I insert a new unmapped identity...

engine.execute('INSERT INTO EXAMPLE_TYPES (TYPE) VALUES (\'C\')')
session.query(BaseType).first()

...things break.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../SQLAlchemy-0.6.5-py2.6.egg/sqlalchemy/orm/query.py", line 1619, in first
    ret = list(self[0:1])
  File ".../SQLAlchemy-0.6.5-py2.6.egg/sqlalchemy/orm/query.py", line 1528, in __getitem__
    return list(res)
  File ".../SQLAlchemy-0.6.5-py2.6.egg/sqlalchemy/orm/query.py", line 1797, in instances
    rows = [process[0](row, None) for row in fetch]
  File ".../SQLAlchemy-0.6.5-py2.6.egg/sqlalchemy/orm/mapper.py", line 2179, in _instance
    _instance = polymorphic_instances[discriminator]
  File ".../SQLAlchemy-0.6.5-py2.6.egg/sqlalchemy/util.py", line 83, in __missing__
    self[key] = val = self.creator(key)
  File ".../SQLAlchemy-0.6.5-py2.6.egg/sqlalchemy/orm/mapper.py", line 2341, in configure_subclass_mapper
    discriminator)
AssertionError: No such polymorphic_identity u'C' is defined

What I expected:

>>> result = session.query(BaseType).first()
>>> result
<BaseType object at 0x1c8db70>
>>> result.type
u'C'

I think this used to work with some older version of SQLAlchemy, but I haven't been keeping up with the development lately. Any pointers on how to accomplish this?

© Stack Overflow or respective owner

Related posts about python

Related posts about sqlalchemy