On 12/17/2011 12:10 PM, Michael Bayer wrote:
On Dec 17, 2011, at 11:32 AM, Kent wrote:

Hate to bother again, but I've been down this road several times and
even created a less than adequate solution but am determined to make
this area more usable:

Problem: I'd like to easily be able to specify to a query
"disable_other_eagerloads", in a manner similar to
enable_eagerloads(False), except it only affects relationships not
specifically joined/subquery loaded for that query.

I've taken to heart comments you've made more than once about avoiding
marking lazy=False in the relationship mappings.  In fact, I've seen
they have a very evil side, I've tried to portrait them as potentially
evil to the engineers I work with who would more happily take the lazy
approach of eagerloading everything in the mappers so they don't have
to think about it. I've also removed the majority of them.

Still, there are relationships that, far more often than not will need
to be joinloaded, so some are still marked as lazy=False.  I suspect I
may rip my hair out someday and remove every last one of them, but in
the meantime, a query option that shuts off all those you haven't
specifically mentioned in the query would be very useful.

You turn them off with the lazyload() option.    Guessing you want this 
generically.  You'd build a function that iterates through 
mapper.get_properties() for each entity in the Query, checks each 
MapperProperty with isinstance(x, RelationshipProperty), checks lazy=False, 
then adds it to a list.    Output is a collection of lazyload() options you 
send to options:

query.options(*lazyload_all_except("x", "y"))

Keep in mind this doesn't have to traverse deeply, only on the attributes that 
are immediately present.

A more comprehensive way would be to subclass MapperOption and have it actually 
look and see what joinedloads are already present, though that requires knowing 
about the conventions that the loader options use within the query._attributes 
dictionary.     It also would have to be the last thing you call on options.   
A feature might look like that.  Or it would put in some other symbol into 
query._attributes that everyone needs to check.      compare to 
http://www.sqlalchemy.org/trac/ticket/1418 .

Yeah, the approach that iterates over the properties you don't pass is the one I wrote a bit back, even called it .lazyload_except(). But that's what I referred to as the "

less than adequate solution".  I want it to be much easier to use so I'm not 
requiring the user to specify the joinedloads twice (once for the joinedload and 
once for the .lazyload_except().  So i'm after your second alternative.

_get_context_strategy() looks promising to me.  By default, if a relationship 
(or column, in the case of ticket #1418) isn't specified in the 
context.attributes as a 'loaderstrategy', then self. strategy is returned.

    def _get_context_strategy(self, context, path):
        cls = context.attributes.get(('loaderstrategy',
                _reduce_path(path)), None)
        if cls:
            try:
                return self.__all_strategies[cls]
            except KeyError:
                return self.__init_strategy(cls)
        else:
            return self.strategy


I can reference the query from the context and then change the default behavior 
to return a self.__init_strategy(LazyLoader) if the query has been told to lazy 
load all others?

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

Reply via email to