On 11/03/2015 07:32 AM, Mattias Lagergren wrote:
Hi Michael,

I've been putting together a self-contained example. If you save it to a
file test_model you should be able to run it:


what's the SQL output with echo=True on the engine? is the subquery for context rendered in the SQL and is it correct?

What happens if you load just a Context object by itself?


the example here isn't exactly "self contained" because it loads data that's not there. Also there's no need to "import test_model", "cls", right there is the Context object.

What happens if you run the example using no inheritance at all?

It might be possible that __declare_last__() isn't appropriate here, can you try just saying "Context.link = column_property()"... right after you declare Context?




|

importsqlalchemy
importsqlalchemy.orm
importsqlalchemy.inspection
importsqlalchemy.ext.declarative

DATABASE_URL =<database-url>

Base=sqlalchemy.ext.declarative.declarative_base()


classContext(Base):
'''Represent a context.'''

     context_type =sqlalchemy.Column(
         sqlalchemy.types.Unicode(32),nullable=False
)

     __mapper_args__ ={
'polymorphic_on':context_type,
'polymorphic_identity':'context'
}

     __tablename__ ='context'

     name =sqlalchemy.Column(
         sqlalchemy.types.Unicode(255),default=u'',nullable=False
)

     id =sqlalchemy.Column(
         sqlalchemy.types.CHAR(36),primary_key=True
)

@classmethod
def__declare_last__(cls):
'''Return link expression query.'''

# Import this module.
importtest_model ascontext
         context =sqlalchemy.orm.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 =sqlalchemy.orm.column_property(
             sqlalchemy.select(
[context.c.name +' '+context.c.context_type],
                 from_obj=[context]
).where(
                 context.c.id ==cls.id
).label('link')
)


classTask(Context):
'''Represent a task.'''

     __tablename__ ='task'

     __mapper_args__ ={
'polymorphic_identity':'task'
}

     taskid =sqlalchemy.Column(
         sqlalchemy.types.CHAR(36),
         sqlalchemy.ForeignKey('context.id'),
         primary_key=True
)


classAsset(Base):
'''Represent an Asset.'''

     __tablename__ ='asset'

     assetid =sqlalchemy.Column(
         sqlalchemy.types.CHAR(36),primary_key=True
)

     context_id =sqlalchemy.Column(
         sqlalchemy.CHAR(36),sqlalchemy.ForeignKey('context.id')
)

     parent =sqlalchemy.orm.relationship(
'Context'
)


if__name__ =='__main__':
print'Loaded attributes: '

# Create engine.
     engine =sqlalchemy.create_engine(
         DATABASE_URL
)
Session=sqlalchemy.orm.sessionmaker(bind=engine)
     session =Session()

     entity =session.query(
Asset
).options(
         sqlalchemy.orm.joinedload('parent')
).first()

     state =sqlalchemy.inspection.inspect(entity.parent)
forattribute instate.attrs:
         is_loaded =(
             attribute.loaded_value isnot
             sqlalchemy.orm.base.NO_VALUE
)
ifis_loaded:
printattribute.key

|




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.

    |
    importsqlalchemy.orm
    importsqlalchemy.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)
    forattribute instate.attrs:
                 is_loaded =(
                     attribute.loaded_value isnot
                     sqlalchemy.orm.base.NO_VALUE
    )
    ifis_loaded:
    printattribute.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
    <http://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:

    |

    classContext(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
    defid(cls):
    returnColumn(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')
    )

    classTask(Context):
    '''Represent a task.'''

         taskid =Column(
             types.CHAR(36),
    ForeignKey('context.id <http://context.id>'),
             primary_key=True
    )

         __mapper_args__ ={
    'polymorphic_identity':'task'
    }


    classAsset(Base):
    '''Represent an Asset.'''

         context_id =sqlalchemy.Column(
             sqlalchemy.CHAR(36),sqlalchemy.ForeignKey('context.id
    <http://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
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

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

Reply via email to