And by the way, if you agree with that direction of things, I'd
happily work on a patch for the query-on-relation thing.

On 3/26/07, Gaetan de Menten <[EMAIL PROTECTED]> wrote:
> On 3/23/07, Michael Bayer <[EMAIL PROTECTED]> wrote:
>
> > OK, this is actually something people have asked for a lot.  in the
> > beginning, recently, etc.  also for different reasons...i.e.
> > convenience, or performance, etc.   So, first off let me start by
> > illustrating how this use case is done right now.   Assuming your
> > Address mapper has a backref "user" to the User mapper, its  just:
> >
> >         for address in 
> > session.query(Address).filter_by(user=someuser).filter
> > (address_table.c.postcode == 5000):
> >                 print address.street
>
> Once again, I discover a "better way" to do something I did the hard way.
>
> > But,  the join conditions and bind params which
> > have been calculated by "LazyLoader" are just sitting there, they can
> > be currently pulled out with a little non-API attribute access but
> > Ive no problem with adding some API-level accessors to get at the
> > Query object calculated for a particular property (i.e. what you are
> > using in your patch internally).
>
> Yes, please do, that'd probably solve the problem nicely (see below
> how I see things).
>
>
> > now lets look at the way your patch does it.
> >
> >         addresses = user.addresses.filter(address_table.c.postcode == 5000)
>
> > seems easy.  right ?  remember that "user" is now in the session.
> > anyone else that queries for "user" will get that same User
> > instance.  but the rest of the app is going to assume normal
> > relationship semantics on that collection....which means:
>
> How I envisioned things, this wouldn't be a problem, because
> user.addresses.filter(xxx) would return a new, independant list, which
> doesn't affect user.addresses, and is not affected if user.addresses
> has already been accessed or not. This is not what my patch does, I
> know. Sorry for not explaining this in my first mail.
>
> >         print someaddress in user.addresses # <-- FAIL - the address is not
> > present
> >         user.addresses.remove(someaddress) # <-- ERROR - the address is not
> > present
> >
> >         user.addresses.insert(5, someotheraddress) # <-- FAIL - the list is
> > incomplete, ordering will be incorrect
>
> This is only a matter of getattr and __contains__ triggering init,
> right? (At least if we exclude the other problems pointed above).
>
> >         session.flush()  # <-- FAIL - we have to figure out what items were
> > added/removed/unchanged from the collection...but the data's
> > incomplete !
>
> I don't master SQLAlchemy internals but I don't see how that is
> different from when the collection is complete?
>
> > so as long as we can agree on the "its a read-only thing" aspect of
> > this, we're good to go.  otherwise you have to define for me how all
> > those mutating operations are going to work (and even then, its
> > additional core complexity im not sure if i can add to my support-load).
>
> I'm fine with the readonly aspect of it. What I don't like is the fact
> you have to create a readonly relation (lazyloader/whatever/...) in
> advance (ie in your mapper), which is IMHO just a dupe of the normal
> relation and pollutes the mapper. You'd end up with mappers like this:
>
>          mapper(SomeClass, table, properties={
>                  'addresses':relation(Address)
>                  'addresses2':lazyloader(Address)
>          })
>
> which is pretty much as ugly as you can get.
>
> On the other hand, I think that combined with a quick way to have
> predefined filters it might be a nice addition anyway:
>
>          mapper(SomeClass, table, properties={
>                  'addresses': relation(Address)
>                  'local_addresses': lazyloader(Address,
> filter=address.c.postcode==5000)
>          })
>
> But it does in no case replace the "dynamic" "non-polluting" use-case
> I'd like to have. What I had in mind is to reuse normal relations to
> get a query. It feels much more natural and cleaner to me. And I think
> the best compromise would be something along the lines of:
>
> user.addresses: # use standard relation => read/write
> user.addresses.filter(XXX): # returns a query => read only
>
> the code would probably be cleaner if we did something more explicit like:
>
> user.addresses.query # returns the query object that you can filter, etc...
>
> though, as a user, I'd prefer the first solution.
>
> Wouldn't that be possible? I think it should be. You only need to keep
> the deferred approach of the InstrumentedList that I demonstrated in
> my patch, so that the whole list is not fetched before we get the
> query object, which would ruin the whole idea. Of course it was only a
> proof-of-concept patch, but I think it should be fixable.
>
> --
> Gaëtan de Menten
> http://openhex.org
>


-- 
Gaëtan de Menten
http://openhex.org

--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to