the script below is my best guess what we're talking about, it's my original 
test from April 20 2012, and includes an assertion that both Person and 
Engineer get their own tables.  The script runs identically in 0.7 and 0.8, and 
__mapper_args__ is called in the same way in both versions.  If you could 
provide a complete and specific test script that refers to the behavior you're 
talking about that would be helpful.

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr, 
has_inherited_table

Base = declarative_base()

class InheritMixin(object):

    @declared_attr
    def __tablename__(cls):
        return cls.__name__

    @declared_attr
    def id(cls):
        return Column(Integer, primary_key = True)

    @declared_attr
    def __mapper_args__(cls):
        if not has_inherited_table(cls):
            return {'polymorphic_on': 'discriminator'}
        else:
            return {'polymorphic_identity': cls.__name__}

class Inherits(InheritMixin):
    @declared_attr
    def id(cls):
        super_id = super(Inherits, cls).id
        return Column(Integer, ForeignKey(super_id), primary_key = True)

class Person(InheritMixin, Base):
    discriminator = Column(String(50))
    name = Column(String(50))

class Engineer(Inherits, Person):
    job = Column(String(50))


assert Engineer.__table__.name == 'Engineer'
assert Person.__table__.name == 'Person'



On Apr 9, 2013, at 1:43 AM, Gerald Thibault <[email protected]> wrote:

> The code referenced in the above post:
> 
> @declared_attr
>    def __mapper_args__(cls):
>        if not has_inherited_table(cls):
>            return {'polymorphic_on': 'discriminator'}
>        else:
>            return {'polymorphic_identity': cls.__name__}
> 
> 
>  has broken between 0.7.9 and 0.8.0, now that __mapper_args__ is a lambda. 
> The call to has_inherited_table will always return true because mapper_args 
> are evaluated after everything is configured, so the first class in 
> cls__mro__ (which will be class) will now have a table attached to it, while 
> in 0.7.9, the mapper_args would be evaluated during as_declarative and the 
> table would not be present.
> 
> Is there a new way to accomplish the same thing?
> 
> On Tuesday, May 1, 2012 7:15:20 AM UTC-7, Michael Bayer wrote:
> building SQLAlchemy apps graphically, that's extremely challenging good luck 
> ! 
> 
> 
> On May 1, 2012, at 5:19 AM, lars van gemerden wrote: 
> 
> > Well thats the thing, my users will determine the data structure 
> > (graphically) and it is hard to predict what they will come up with. 
> > On the other hand, I am only building a prototype at the moment, so 
> > speed issues (if not easily solved) will have to wait. 
> > 
> > I'll stick with joined inheritance for now (though I'll probalby take 
> > out the unique base class for all classes). 
> > 
> > Thank you again for all the help, 
> > 
> > Lars 
> > 
> > On Apr 27, 3:59 pm, Michael Bayer <[email protected]> wrote: 
> >> concrete inheritance is very challenging overall, if you expect there to 
> >> be any kind of polymorphic interaction between the classes.     if you 
> >> want to query polymorphically then speed will be probably worse.   If you 
> >> can do without polymorphic and stick to each subclass directly it wont 
> >> have an issue. 
> >> 
> >> Usually though if I'm inheriting more than two levels, I'll use joined 
> >> inheritance for level one->two then single table for all levels beyond 
> >> that.   Depends on what you're trying to do. 
> >> 
> >> On Apr 27, 2012, at 3:05 AM, lars van gemerden wrote: 
> >> 
> >> 
> >> 
> >> 
> >> 
> >> 
> >> 
> >>> Ok, so speed might become an issue for me as well; 
> >> 
> >>> Do you think a similar metaclass approach would work for concrete 
> >>> inheritance would work without major drawbacks (before i do a major 
> >>> overhaul)? 
> >>> Is there any indication about how much faster concrete inheritance is, 
> >>> compared to joined inheritance? 
> >> 
> >>> Cheers, Lars 
> >> 
> >>> On Friday, April 20, 2012 9:32:49 PM UTC+2, Michael Bayer wrote: 
> >> 
> >>> On Apr 20, 2012, at 8:51 AM, lars van gemerden wrote: 
> >>>> Ok, thank you, that helps, but now i cannot inherit from Engineer, as 
> >>>> in: 
> >> 
> >>>> class BaseMixin(object): 
> >> 
> >>>>     discriminator = Column(String(50)) 
> >> 
> >>>>     @declared_attr 
> >>>>     def __tablename__(cls): 
> >>>>         return cls.__name__ 
> >>>>     @declared_attr 
> >>>>     def id(cls): 
> >>>>         return Column(Integer, primary_key = True) 
> >>>>     @declared_attr 
> >>>>     def __mapper_args__(cls): 
> >>>>         if not has_inherited_table(cls): 
> >>>>             return {'polymorphic_on': 'discriminator'} 
> >>>>         else: 
> >>>>             return {'polymorphic_identity': cls.__name__} 
> >> 
> >>>> class InheritMixin(BaseMixin): 
> >>>>     @declared_attr 
> >>>>     def id(cls): 
> >>>>         super_id = super(InheritMixin, cls).id 
> >>>>         return Column(Integer, ForeignKey(super_id), primary_key = True) 
> >> 
> >>>> class Person(BaseMixin, Base): 
> >>>>     name = Column(String(50)) 
> >> 
> >>>> class Engineer(InheritMixin, Person): 
> >>>>     job = Column(String(50)) 
> >> 
> >>>> class MasterEngineer(InheritMixin, Engineer): 
> >>>>     specialty = Column(String(50)) 
> >> 
> >>>> Gives an MRO() error and if i would reverse the baseclasses (like class 
> >>>> Engineer(Person, InheritMixin):  ... ), the inheriting classes pick up 
> >>>> the wrong id. 
> >> 
> >>>> Do you see any solution for this? 
> >> 
> >>> yeah I suppose if you're building out joined inheritance more than one 
> >>> level then this becomes awkward.   I never use joined inh more than one 
> >>> level because it has too much of an impact on queries. 
> >> 
> >>> the metaclass as you mention is always the last resort when the various 
> >>> declarative trickery reaches its limit.   I'm not thrilled about the 
> >>> metaclass approach because it quickly gets confusing and shouldn't be 
> >>> necessary.   though in this case without some extra mechanism on 
> >>> declarative, such as a __pre_declare__() method of some kind, it might be 
> >>> the only approach. 
> >> 
> >>> -- 
> >>> You received this message because you are subscribed to the Google Groups 
> >>> "sqlalchemy" group. 
> >>> To view this discussion on the web 
> >>> visithttps://groups.google.com/d/msg/sqlalchemy/-/MH4tZazKT0EJ. 
> >>> To post to this group, send email to [email protected]. 
> >>> To unsubscribe from this group, send email to 
> >>> [email protected]. 
> >>> For more options, visit this group 
> >>> athttp://groups.google.com/group/sqlalchemy?hl=en. 
> > 
> > -- 
> > You received this message because you are subscribed to the Google Groups 
> > "sqlalchemy" group. 
> > To post to this group, send email to [email protected]. 
> > To unsubscribe from this group, send email to 
> > [email protected]. 
> > For more options, visit this group at 
> > http://groups.google.com/group/sqlalchemy?hl=en. 
> > 
> 
> 
> -- 
> 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.
>  
>  

-- 
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.


Reply via email to