On Sep 8, 2010, at 1:15 PM, Kent Bower wrote:

> I imagine you are already aware of this...
> 
> Unfortunately, the clause comparison says these two clauses are different:
> 
> (Pdb) print self
> locations.siteid = :param_1 AND locations.locationid = :param_2
> (Pdb) print other
> locations.locationid = :param_1 AND locations.siteid = :param_2
> 
> when they are really the equivalent.  So composite foreign keys need to be 
> listed in the correct order for LazyLoader.use_get to optimize the load with 
> get().

use clause.compare().   Here's the source for _BinaryExpression:

    def compare(self, other, **kw):
        """Compare this :class:`_BinaryExpression` against the 
        given :class:`_BinaryExpression`."""

        return (
            isinstance(other, _BinaryExpression) and
            self.operator == other.operator and
            (
                self.left.compare(other.left, **kw) and
                self.right.compare(other.right, **kw) or
                (
                    operators.is_commutative(self.operator) and
                    self.left.compare(other.right, **kw) and
                    self.right.compare(other.left, **kw)
                )
            )
        )


see the "commutative" in there ?  its handled.




> 
> I already saw it would be somewhat of an effort to refactor the clause 
> comparison to work that out... bummer.
> 
> 
> 
> 
> On 9/7/2010 7:28 PM, Michael Bayer wrote:
>> 
>> 
>> On Sep 7, 2010, at 6:41 PM, Kent Bower wrote:
>> 
>>> Two items:
>>> 
>>>  * How does the orm currently determine whether it is safe to try get() 
>>> (e.i. there are no "funny join conditions")?  If you point me to the 
>>> function where decision takes place, I can probably answer this myself....
>> 
>> it compares the join condition of the relationship() to that of the clause 
>> which the Mapper uses when it issues get(), then stores that away as a flag 
>> for future consultation.   It's very unusual for a many-to-one relationship 
>> to be based on something other than a simple foreign-key->primary key 
>> relationship, though.
>> 
>> 
>>> 
>>>  * When I build up the primary key from the foreign key, is there an 
>>> efficient way to build a composite key in the correct order to pass to 
>>> get()?  (I thought maybe "synchronize_pairs", but that maybe has to do with 
>>> getting the direction consistent instead?)  
>> 
>> Well if you aren't using any composite primary keys in many-to-ones, you 
>> wouldn't even have to worry about this.   Otherwise, the two collections to 
>> correlate would be property.local_remote_pairs and 
>> property.mapper.primary_key.   Perhaps make a dictionary out of dict([(r, l) 
>> for l, r in prop.local_remote_pairs]) and your PK value would be 
>> [getattr(instance, prop.parent.get_property_by_column(mydict[p]).key) for p 
>> in property.mapper.primary_key].
>> 
>> Or if you want to get ambitious you can just copy roughly whats in 
>> strategies.py on line 605 but then you're digging into internals....and 
>> looking at that now I'm wondering if strategy._equated_columns is really 
>> different than local_remote_pairs at all...
>> 
>> 
>> 
>>> 
>>> Thanks again, you've been much help!
>>> 
>>> 
>>> 
>>> On 9/7/2010 5:03 PM, Michael Bayer wrote:
>>>> 
>>>> 
>>>> On Sep 7, 2010, at 4:38 PM, Kent Bower wrote:
>>>> 
>>>>> Don't want to strangle me, but when the orm (lazy)loads a MANYTONE 
>>>>> object, it doesn't go to the database if the object is in the session.  
>>>>> Can I get "with_parent()" to behave this way, or would I need to 
>>>>> specifically build up the primary key of the related object and call 
>>>>> query.get()?
>>>> 
>>>> the latter.   You can use get() for all many to ones if you aren't using 
>>>> any funny join conditions.
>>>> 
>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> On 9/7/2010 10:25 AM, Michael Bayer wrote:
>>>>>> 
>>>>>> 
>>>>>> On Sep 7, 2010, at 10:12 AM, Kent Bower wrote:
>>>>>> 
>>>>>>> Mike, in your proof of concept, when __getstate__ detected transient, 
>>>>>>> why did you need to make a copy of self.__dict__? "self.__dict__.copy()"
>>>>>> 
>>>>>> i was modifying the __dict__ from what would be expected in a 
>>>>>> non-serialized object, so that was to leave the original object being 
>>>>>> serialized unchanged.
>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> On 9/6/2010 2:35 PM, Michael Bayer wrote:
>>>>>>>> 
>>>>>>>> On Sep 6, 2010, at 2:11 PM, Kent Bower wrote:
>>>>>>>> 
>>>>>>>>> Also, I was hoping you would tell me whether this would be a 
>>>>>>>>> candidate for subclassing InstrumentedAttribute?  Would that make 
>>>>>>>>> more sense or providing custom __getstate__ & __setstate__ ?
>>>>>>>> __getstate__ / __setstate__ are pretty much what I like to use for 
>>>>>>>> pickle stuff, unless some exotic situation makes me have to use 
>>>>>>>> __reduce__.   One problem with the recipe is that theres no 'deferred' 
>>>>>>>> loading of attributes.   So in that sense playing with 
>>>>>>>> InstrumentedAttribute would give you a chance to put a callable in 
>>>>>>>> there that does what you want.
>>>>>>>> 
>>>>>>>> There is also the possibility that __setstate__ can load up callables 
>>>>>>>> into the instance_state using state.set_callable().   This is a 
>>>>>>>> callable that triggers when you access the attribute that is otherwise 
>>>>>>>> None.   There's a little bit of fanfare required to get that callable 
>>>>>>>> to assign to the attribute in the right way.   Attached is an example 
>>>>>>>> of that.   This is all a little more shaky since the state/callable 
>>>>>>>> API isn't really public.  Hasn't changed for awhile but there's no 
>>>>>>>> guarantee.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> Thanks for your help, hopefully I'll be able to contribute such a 
>>>>>>>>> recipe. 
>>>>>>>>> 
>>>>>>>>> Kent
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>>> Since sqla won't load that for me in the case of transient, I need 
>>>>>>>>>>> to load the relation manually (unless you feel like enhancing that 
>>>>>>>>>>> as well). 
>>>>>>>>>> its not an enhancement - it was a broken behavior that was 
>>>>>>>>>> specifically removed.   The transient object has no session, so 
>>>>>>>>>> therefore no SQL can be emitted - there's no context established.  
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>> Now I can manually emulate the obj being persistent with your 
>>>>>>>>>>> changes for 
>>>>>>>>>>> 
>>>>>>>>>>> On Sep 6, 2010, at 10:58 AM, Michael Bayer 
>>>>>>>>>>> <mike...@zzzcomputing.com> wrote:
>>>>>>>>>>> 
>>>>>>>>>>>> On Sep 6, 2010, at 9:06 AM, Kent wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>>> with_parent seems to add a join condition.  
>>>>>>>>>>>> OK, so I guess you read the docs which is why you thought it 
>>>>>>>>>>>> joined and why you didn't realize it doesn't work for transient.  
>>>>>>>>>>>> r20b6ce05f194 changes all that so that with_parent() accepts 
>>>>>>>>>>>> transient objects and will do the "look at the attributes" thing.  
>>>>>>>>>>>>  The docs are updated as this method does use the lazy loader SQL 
>>>>>>>>>>>> mechanism, not a join.
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>>> Is there a way to get at
>>>>>>>>>>>>> the query object that would be rendered from a lazy load (or what
>>>>>>>>>>>>> "subqueryload" would render on the subsequent load), but on a
>>>>>>>>>>>>> transient object, if i supply the session?
>>>>>>>>>>>>> 
>>>>>>>>>>>>> even though not "recommended", can it make sqla believe my 
>>>>>>>>>>>>> transient
>>>>>>>>>>>>> object is detached by setting its state key?
>>>>>>>>>>>>> 
>>>>>>>>>>>>> There are reasons i do not want to add this to the session and
>>>>>>>>>>>>> disabling autoflush would also cause problems.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> On Sep 3, 9:58 am, Michael Bayer <mike...@zzzcomputing.com> wrote:
>>>>>>>>>>>>>> On Sep 3, 2010, at 9:36 AM, Kent wrote:
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> For the case of customerid = '7', that is a simple problem, but 
>>>>>>>>>>>>>>> when
>>>>>>>>>>>>>>> it is a more complex join condition, we only wanted to define 
>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>> condition in one single place in our application (namely, the 
>>>>>>>>>>>>>>> orm).
>>>>>>>>>>>>>>> That way, if or when that changes, developers don't need to 
>>>>>>>>>>>>>>> search for
>>>>>>>>>>>>>>> other places in the app that needed to manually duplicate the 
>>>>>>>>>>>>>>> logic of
>>>>>>>>>>>>>>> the orm join condition.
>>>>>>>>>>>>>>> If I supplied the DBSession to sqla, it would know how to 
>>>>>>>>>>>>>>> create the
>>>>>>>>>>>>>>> proper Query object for this lazyload.  Can you point me in the 
>>>>>>>>>>>>>>> right
>>>>>>>>>>>>>>> direction (even if where you point me is not currently part of 
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> public API)?
>>>>>>>>>>>>>> Query has the with_parent() method for this use case.  
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> Thanks again,
>>>>>>>>>>>>>>> Kent
>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>> You received this message because you are subscribed to the 
>>>>>>>>>>>>>>> Google Groups "sqlalchemy" group.
>>>>>>>>>>>>>>> To post to this group, send email to 
>>>>>>>>>>>>>>> sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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 sqlalch...@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