Here is a test. It's possible the failure is because the provided example uses a mixin, while i am declaring directly on the base class.
from sqlalchemy import * from sqlalchemy.ext.declarative import (declarative_base, declared_attr, has_inherited_table) Base = declarative_base() class Test(Base): __tablename__ = 'test' id = Column(Integer, primary_key=True) type = Column(String(20)) @declared_attr def __mapper_args__(cls): if not has_inherited_table(cls): ret = { 'polymorphic_identity': 'default', 'polymorphic_on': cls.type, } else: ret = {'polymorphic_identity': cls.__name__} print '%s.__mapper_args__:' % cls print ret return ret class PolyTest(Test): __tablename__ = 'poly_test' id = Column(Integer, ForeignKey(Test.id), primary_key=True) Running this under 0.7.9 produces: <class '__main__.Test'>.__mapper_args__: {'polymorphic_identity': 'default', 'polymorphic_on': Column(None, String(length=20), table=None)} <class '__main__.Test'>.__mapper_args__: {'polymorphic_identity': 'default', 'polymorphic_on': Column(None, String(length=20), table=None)} <class '__main__.PolyTest'>.__mapper_args__: {'polymorphic_identity': 'PolyTest'} Running under 0.8.0 produces: <class '__main__.Test'>.__mapper_args__: {'polymorphic_identity': 'Test'} <class '__main__.PolyTest'>.__mapper_args__: {'polymorphic_identity': 'PolyTest'} in 7.9, the polymorphic_on was set correctly, in 8.0 the table already exists when the mapper_args are processed (because it's a lambda now), so has_inherited_table returns True. Is it intended behavior to have has_inherited_table return true when the only "inherited" table is that on the class itself? I am working around this by using my own has_inherited_table method, which first checks if the base is equal to the active class, and skipping it if they're the same. It seems this should be default behavior, unless i am misunderstanding what 'inherited' is representing here. Is there a way to accomplish what I'm trying to do without setting up my own has_inherited_table function? On Thursday, April 19, 2012 3:23:54 AM UTC-7, lars van gemerden wrote: > > I am trying to my my joined inheritance code clearer, for the dynamic > generation of sa classes and tried to do something like this: > > > class InheritMixin(object): > > @declared_attr > def __tablename__(cls): > return cls.__name__ > @declared_attr > def id(cls): > if cls.__name__ == 'Object': > return Column(Integer, primary_key = True) > else: > print 'in id: ', cls.__name__, cls.__bases__[0].__name__ > return Column(Integer, > ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True) > @declared_attr > def __mapper_args__(cls): > if cls.__name__ == 'Object': > return {'polymorphic_on': 'discriminator'} > else: > print 'in mapper_args: ', cls.__name__, > cls.__bases__[0].__name__ > return {'polymorphic_identity': cls.__name__, > 'inherit_condition': (cls.id == > cls.__bases__[0].id)} > > Object = type('Object', (Base, InheritMixin), clsdict) > > Where Object should be the (not necessarily direct) baseclass of all > inheriting classes. However I get errors: "Mapper Mapper|person|person > could not assemble any primary key columns for mapped table 'Join > object on Object(65389120) and person(65428224)' " etc .. > > I noticed that the method __mapper_args__(cls) is always called before > id(cls) (which is never called, probably due to the error. > > Is there some way to fix this, while keeping the inheritance code in a > mixin? > > Also, is there a way to add the discriminator column to the mixin (if > i just directly add it to the declaration, this gave another maybe > related error)? > > Cheers, Lars > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.