Default class for SQLAlchemy single table inheritance
- by eclaird
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?