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