Hi Michael, thank you for your quick response! Yeah, it seems that I got confused about the "load_only" method - it doesn't load at all. I've tried to put together an easier example to show the problem. It seems that it is related to the joinedload.
import sqlalchemy.orm import sqlalchemy.inspection entity = model.session.query( model.Asset ).options( sqlalchemy.orm.joinedload( 'parent' ) ).first() state = sqlalchemy.inspection.inspect(entity.parent) for attribute in state.attrs: is_loaded = ( attribute.loaded_value is not sqlalchemy.orm.base.NO_VALUE ) if is_loaded: print attribute.key And if I omit it, it load s fine. Here is a simplified version of my model: class Context(Base): '''Represent a context.''' context_type = Column(Unicode(32), nullable=False) __mapper_args__ = { 'polymorphic_on': context_type, 'polymorphic_identity': 'context' } @declared_attr def __tablename__(cls): return 'context' name = Column(Unicode(255), default=u'', nullable=False) @declared_attr def id(cls): return Column(CHAR(36), primary_key=True, default=lambda: str(uuid ())) @classmethod def __declare_last__(cls): '''Return link expression query.''' # Import this module. from . import context context = aliased(context.Context.__table__) # My real use-case is more complicated and involves a lot of joinst to other tables, but this example reproduces the # issue. cls.link = column_property( sqlalchemy.select( [context.c.name + ' ' + context.c.context_type], from_obj=[context] ).where( context.c.id == cls.id ).label('link') ) class Task(Context): '''Represent a task.''' @declared_attr def __tablename__(cls): return 'task' @declared_attr def __table_args__(cls): return { 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8' } taskid = Column( types.CHAR(36), ForeignKey('context.id'), primary_key=True ) __mapper_args__ = { 'polymorphic_identity': 'task' } class Asset(Base): '''Represent an Asset.''' @declared_attr def __tablename__(cls): return 'asset' @declared_attr def __table_args__(cls): return { 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8' } context_id = sqlalchemy.Column( sqlalchemy.CHAR(36), sqlalchemy.ForeignKey('context.id') ) parent = relationship('Context', backref=backref('assets')) I hope this example makes more sense. Can you see any obvious problems with my approach and why it wouldn't work? If I add the link as a declared_attr instead it does work: @declared_attr def link(cls): return column_property(cls.name + ' ' + cls.context_type) However, my real-life use-case link is more complicated and I need to do imports that would cause circular import errors if I used declared_attr. Best regards, Mattias L On Monday, November 2, 2015 at 3:16:07 PM UTC+1, Mattias Lagergren wrote: > > Hi, > > I'm trying to use load_only and joinedload on a relationship > model.Asset.parent. The parent relation is polymorphic and can be either > Task or Project with the common Base class called Context. > > import sqlalchemy.orm > import sqlalchemy.inspection > > entity = model.session.query( > model.Asset > ).options( > sqlalchemy.orm.joinedload('parent').load_only( > 'context_type', 'name', 'link' > ) > ).first() > > state = sqlalchemy.inspection.inspect(entity.parent) > for attribute in state.attrs: > is_loaded = ( > attribute.loaded_value is not > sqlalchemy.orm.base.NO_VALUE > ) > if is_loaded: > print attribute.key > > # Output: > id > taskid > name > context_type > > > The id, name and context_type is from Context. And taskid is primary key > on the taskid and is a foreignkey to the context.id. As you can see > "name" loads fine but "link" attribute is not loaded. The "link" column is > added as a column_property to Context using a __declare_last__. > > These are simplified versions of the classes: > > > class Context(Base): > '''Represent a context.''' > context_type = Column(Unicode(32), nullable=False) > > __mapper_args__ = { > 'polymorphic_on': context_type, > 'polymorphic_identity': 'context' > } > > name = Column(Unicode(255), default=u'', nullable=False) > > @declared_attr > def id(cls): > return Column(CHAR(36), primary_key=True, default=lambda: str(uuid > ())) > > @classmethod > def __declare_last__(cls): > '''Return link expression query.''' > > ... > > cls.link = column_property( > sqlalchemy.type_coerce( > query, LinkTypeDecorator > ).label('link') > ) > > class Task(Context): > '''Represent a task.''' > > taskid = Column( > types.CHAR(36), > ForeignKey('context.id'), > primary_key=True > ) > > __mapper_args__ = { > 'polymorphic_identity': 'task' > } > > > class Asset(Base): > '''Represent an Asset.''' > > context_id = sqlalchemy.Column( > sqlalchemy.CHAR(36), sqlalchemy.ForeignKey('context.id') > ) > > parent = relationship('Context', backref=backref('assets')) > > > Can you see if I'm doing something wrong? > -- 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 sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.