this is the testcase: from sqlalchemy import * from sqlalchemy.orm.session import sessionmaker from sqlalchemy.ext.declarative import declarative_base, declared_attr
engine = create_engine('sqlite:///:memory:', echo=False) Base = declarative_base(bind = engine) Session = sessionmaker(bind = engine) def setup(engine): Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) return Session() class InheritMixin(object): @declared_attr def __tablename__(cls): return cls.__name__ @declared_attr def id(cls): if Base in cls.__bases__: print 'base in id(cls): ', cls return Column(Integer, primary_key = True) else: print 'in id(cls): ', cls, cls.__bases__[0] return Column(Integer, ForeignKey(cls.__bases__[0].id), primary_key = True) @declared_attr def __mapper_args__(cls): if Base in cls.__bases__: print 'base in __mapper_args__(cls): ', cls return {'polymorphic_on': 'discriminator'} else: print 'in __mapper_args__(cls): ', cls, cls.__bases__[0], cls.id, (cls.id is cls.__bases__[0].id) return {'polymorphic_identity': cls.__name__} class Person(Base, InheritMixin): discriminator = Column(String(50)) name = Column(String(50)) class Engineer(Person): job = Column(String(50)) if __name__ == '__main__': session = setup(engine) a = Person(name = 'ann') b = Engineer(name = 'bob', job = 'car repair') session.add_all([a, b]) session.commit() people = session.query(Person).all() print people Note that i left out the 'inherit_condition', because without there is already a problem: base in id(cls): <class '__main__.Person'> base in mapper_args(cls): <class '__main__.Person'> in mapper_args(cls): <class '__main__.Engineer'> <class '__main__.Person'> Person.id True Traceback (most recent call last): File "D:\Documents\Code\Eclipse\workspace\process_data3\src \little_tests2.py", line 40, in <module> class Engineer(Person): File "C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py", line 1336, in __init__ _as_declarative(cls, classname, cls.__dict__) File "C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py", line 1329, in _as_declarative **mapper_args) File "C:\Python27\lib\site-packages\sqlalchemy\orm\__init__.py", line 1116, in mapper return Mapper(class_, local_table, *args, **params) File "C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py", line 197, in __init__ self._configure_inheritance() File "C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py", line 473, in _configure_inheritance self.local_table) File "C:\Python27\lib\site-packages\sqlalchemy\sql\util.py", line 303, in join_condition "between '%s' and '%s'.%s" % (a.description, b.description, hint)) sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships between 'Person' and 'Engineer'. What am i missing? Cheers, Lars On Apr 19, 4:13 pm, Michael Bayer <mike...@zzzcomputing.com> wrote: > On Apr 19, 2012, at 6:23 AM, 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 .. > > im not sure of the cause of that error, can you attach a full test case which > illustrates this message being generated ? > > > > > I noticed that the method __mapper_args__(cls) is always called before > > id(cls) (which is never called, probably due to the error. > > the __mapper_args__(cls) method here directly calls upon .id, so if you see > .id() not being called it suggests some other form of .id is being used. > > Is it possible that Base or something else has a conflicting "id" attribute? > > > > > 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)? > > maybe, let's start with the general idea of the mixin you're going to send me > as a working script. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.