@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 at > http://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.