Thanks for clearing that up. "__abstract__ = True" looks like a nice
addition. In this case, I decided to go with the metaclass approach,
i.e. declaring the attributes as usual, and then delete them if
necessary in the metaclass.

On Sep 23, 1:36 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> @declared_attr when used for attributes outside of __table_args__, 
> __tablename__ and __mapper_args__ is only recognized on a mixin, or on a 
> class that uses a new directive "__abstract__ = True".  It's skipped on 
> mapped classes when used for plain column attributes since inheriting from a 
> mapped class means you're using mapper inheritance - and in the usual case of 
> single- or joined-table inheritance, the subclass specifically should not get 
> copies of columns on the superclass.   So really @declared_attr returning a 
> column on the mapped class should be raising an error here, perhaps I'll make 
> it emit a warning for the time being since it will not do anything useful.
>
> If you'd like to put a non-mixin class in the middle of your hierarchy that 
> can define columns that immediate subclasses should have, use the tip of 0.7 
> (0.7.3 not released yet) and put the directive "__abstract__ = True" on the 
> class - the @declared_attr's on columns should be recognized in that case.   
> You wouldn't want to have "__tablename__ = 'test'" on such a class either 
> since it isn't mapped.
>
> On Sep 23, 2011, at 12:48 AM, Yap Sok Ann wrote:
>
>
>
>
>
>
>
> > With this code:
>
> > from sqlalchemy.ext.declarative import declarative_base, declared_attr
> > from sqlalchemy.schema import Column
> > from sqlalchemy.types import Integer, String
>
> > Base = declarative_base()
>
> > class Mixin(object):
> >    @declared_attr
> >    def attr2(cls):
> >        return Column(String(20), nullable=False)
>
> > class Test(Base, Mixin):
> >    __tablename__ = 'test'
>
> >    id = Column(Integer, primary_key=True)
>
> >    @declared_attr
> >    def attr1(cls):
> >        return Column(String(20), nullable=False)
>
> > if __name__ == '__main__':
> >    print Test.attr1.__class__
> >    print Test.attr2.__class__
>
> > Test.attr1 will be a sqlalchemy.schema.Column, while Test.attr2 will
> > be a sqlalchemy.orm.attributes.InstrumentedAttribute. Why are they
> > behave differently?
>
> > Anyway, what I want to achieve is to selectively define a column based
> > on some external flag, so I was trying to put in if..else block inside
> > @declared_attr to return either None or Column. Is there a better way
> > to do it, e.g. using a metaclass?
>
> > Thanks.
>
> > --
> > 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 
> > 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 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.

Reply via email to