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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.