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