[sqlalchemy] Re: [PATCH] filter_by_via
On 6/2/07, Michael Bayer [EMAIL PROTECTED] wrote: On Jun 2, 2007, at 6:02 AM, Gaetan de Menten wrote: Hmmm, after some more thoughts there is one little aspect of that which bothers me: once you joined to something, you can't add filtering criteria on the initial table/class. This is actually one of the features I disliked about the current code. It might be rare use case but I, for one, like to be able to construct queries in any order, so that I can factor out the common part and store it somewhere then add what is specific at a later point. Here, if the specific part is about the initial table, I'm screwed. Adding a method to just move/reset the joinpoint would solve this, though I find it ugly. Better than nothing though. This would look like this: q = session.query(User).join(['orders', 'items']).filter_by (item_name='foo'). user_query = q.join(['addresses']).filter_by (email_address='[EMAIL PROTECTED]').reset_joinpoint() users = user_query.filter_by(name='Foo').list() yeah i had that idea as well, and yeah its a little ugly. theres also the possiblity of using join(None). let me summarize things that im thinking we do: - we want to go with the joinpoint concept here, where join() starts from the beginning, and join(None)/reset_joinpoint brings it back. I'd personally vote for join(None). Seem pretty logical if join starts from the beginning and doesn't introduce a new method (IMHO there are already too many of them on query objects). join() is used to add a join and also modify the joinpoint of the query, so that you can add more criterion using filter() or filter_by () or others. I think this particuar tweak would probably even be OK to put in the current trunk for release 0.3.8 unless people think its going to create problems...the only backwards-incompatible change being a join() starts from the beginning, not the previous join(). - i think filter_by(['list','of','properties'], **kwargs), i.e. an optional, positional string/list-of-strings argument, should also be present, and it will create the joins and criterion using table aliases, and will not be related to joinpoint at all. apparently django does this, and it would let us define criterion for multiple overlapping paths, such as q.filter_by(['a', 'b, 'c'], d=x).filter_by (['a', 'b', 'e'], d=x). thats something that you cant do with the straight join() alone (but of course you can do with explicit aliases and filter()/select_from()). That'd be pretty nice to have that alias feature, because in that case you could join several times to the same table through different relationships easily. - the auto find me a property behavior is gone. not sure if I want to remove it from select_by() and friends, i think it should probably remain in those in a deprecated state. - ClauseElement support would be removed from filter_by(). you can just use filter() for those. the older _by() methods, which i want to deprecate, would be left alone for backwards compatibility. What do you replace order_by with? - i want to deprecate all the criterion methods that are not filter, i.e. all the selects and most of the gets (except straight get()). selecting from a full statement we can do with query.from_statement (select statement), the argument of which is a select() or a string. deprecating select() and select_by() is to create a single simple interface to query based on the more flexible filter(). but it does mean a bit more typing in many cases. I would hope everyone is OK with that. I'd personally like this but that's probably because I don't use those much. But I think many people are using those so that might be an unpopular move. As such, it would probably deserve a thread on its own, so that people would actually have a chance to react... -- 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Jun 3, 2007, at 8:10 AM, Gaetan de Menten wrote: - ClauseElement support would be removed from filter_by(). you can just use filter() for those. the older _by() methods, which i want to deprecate, would be left alone for backwards compatibility. What do you replace order_by with? oh, no we leave order_by() (and group_by()), by _by() i meant the selecting functions like select_by(), selectfirst_by(), etc. - i want to deprecate all the criterion methods that are not filter, i.e. all the selects and most of the gets (except straight get()). selecting from a full statement we can do with query.from_statement (select statement), the argument of which is a select() or a string. deprecating select() and select_by() is to create a single simple interface to query based on the more flexible filter(). but it does mean a bit more typing in many cases. I would hope everyone is OK with that. I'd personally like this but that's probably because I don't use those much. But I think many people are using those so that might be an unpopular move. As such, it would probably deserve a thread on its own, so that people would actually have a chance to react... OK then...though I dont see how we can really keep them. the docs / explanation of query would become so much simpler with only one obvious way to specify filtering criterion / adjustments etc. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
IMHO, this solves my use case nicely. It's slightly longer than what I proposed but doesn't reach my internal this_is_too_long_to_type threshold and it's more explicit... So for me it's a +1 for that solution (along with documenting the joinpoint behavior ;-)). On 6/2/07, Michael Bayer [EMAIL PROTECTED] wrote: plus *another* option to think about here, which was actually my first (suppressed) instinct, but now i just saw that Hibernate sort of does this, is to *keep* the joinpoint in and just have the join function reset the joinpoint on each invocation. so, session.query(User).join(['orders', 'items']).filter_by (item_name='foo').join(['addresses']).filter_by (email_address='[EMAIL PROTECTED]').list() at the moment, this seems intuitive to me. but i dont know if itll stay that way. i do like that each method has a single type of argument, as opposed to filter_by(qualifier, **kwargs). -- 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On 6/2/07, Gaetan de Menten [EMAIL PROTECTED] wrote: IMHO, this solves my use case nicely. It's slightly longer than what I proposed but doesn't reach my internal this_is_too_long_to_type threshold and it's more explicit... So for me it's a +1 for that solution (along with documenting the joinpoint behavior ;-)). Hmmm, after some more thoughts there is one little aspect of that which bothers me: once you joined to something, you can't add filtering criteria on the initial table/class. This is actually one of the features I disliked about the current code. It might be rare use case but I, for one, like to be able to construct queries in any order, so that I can factor out the common part and store it somewhere then add what is specific at a later point. Here, if the specific part is about the initial table, I'm screwed. Adding a method to just move/reset the joinpoint would solve this, though I find it ugly. Better than nothing though. This would look like this: q = session.query(User).join(['orders', 'items']).filter_by(item_name='foo'). user_query = q.join(['addresses']).filter_by(email_address='[EMAIL PROTECTED]').reset_joinpoint() users = user_query.filter_by(name='Foo').list() On 6/2/07, Michael Bayer [EMAIL PROTECTED] wrote: plus *another* option to think about here, which was actually my first (suppressed) instinct, but now i just saw that Hibernate sort of does this, is to *keep* the joinpoint in and just have the join function reset the joinpoint on each invocation. so, session.query(User).join(['orders', 'items']).filter_by (item_name='foo').join(['addresses']).filter_by (email_address='[EMAIL PROTECTED]').list() at the moment, this seems intuitive to me. but i dont know if itll stay that way. i do like that each method has a single type of argument, as opposed to filter_by(qualifier, **kwargs). -- 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Jun 2, 2007, at 6:02 AM, Gaetan de Menten wrote: Hmmm, after some more thoughts there is one little aspect of that which bothers me: once you joined to something, you can't add filtering criteria on the initial table/class. This is actually one of the features I disliked about the current code. It might be rare use case but I, for one, like to be able to construct queries in any order, so that I can factor out the common part and store it somewhere then add what is specific at a later point. Here, if the specific part is about the initial table, I'm screwed. Adding a method to just move/reset the joinpoint would solve this, though I find it ugly. Better than nothing though. This would look like this: q = session.query(User).join(['orders', 'items']).filter_by (item_name='foo'). user_query = q.join(['addresses']).filter_by (email_address='[EMAIL PROTECTED]').reset_joinpoint() users = user_query.filter_by(name='Foo').list() yeah i had that idea as well, and yeah its a little ugly. theres also the possiblity of using join(None). let me summarize things that im thinking we do: - we want to go with the joinpoint concept here, where join() starts from the beginning, and join(None)/reset_joinpoint brings it back. join() is used to add a join and also modify the joinpoint of the query, so that you can add more criterion using filter() or filter_by () or others. I think this particuar tweak would probably even be OK to put in the current trunk for release 0.3.8 unless people think its going to create problems...the only backwards-incompatible change being a join() starts from the beginning, not the previous join(). - i think filter_by(['list','of','properties'], **kwargs), i.e. an optional, positional string/list-of-strings argument, should also be present, and it will create the joins and criterion using table aliases, and will not be related to joinpoint at all. apparently django does this, and it would let us define criterion for multiple overlapping paths, such as q.filter_by(['a', 'b, 'c'], d=x).filter_by (['a', 'b', 'e'], d=x). thats something that you cant do with the straight join() alone (but of course you can do with explicit aliases and filter()/select_from()). - the auto find me a property behavior is gone. not sure if I want to remove it from select_by() and friends, i think it should probably remain in those in a deprecated state. - ClauseElement support would be removed from filter_by(). you can just use filter() for those. the older _by() methods, which i want to deprecate, would be left alone for backwards compatibility. - i want to deprecate all the criterion methods that are not filter, i.e. all the selects and most of the gets (except straight get()). selecting from a full statement we can do with query.from_statement (select statement), the argument of which is a select() or a string. deprecating select() and select_by() is to create a single simple interface to query based on the more flexible filter(). but it does mean a bit more typing in many cases. I would hope everyone is OK with that. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
what about adding a docopy=True (or dont_copy=False) to all methods that could be both copy_generative and modify-in-place? via some generic self=self.copy_if_required() func? Then one can choose at which point to split+copy let me summarize things that im thinking we do: - we want to go with the joinpoint concept here, where join() starts from the beginning, and join(None)/reset_joinpoint brings it back. join() is used to add a join and also modify the joinpoint of the query, so that you can add more criterion using filter() or filter_by () or others. I think this particuar tweak would probably even be OK to put in the current trunk for release 0.3.8 unless people think its going to create problems...the only backwards-incompatible change being a join() starts from the beginning, not the previous join(). - i think filter_by(['list','of','properties'], **kwargs), i.e. an optional, positional string/list-of-strings argument, should also be present, and it will create the joins and criterion using table aliases, and will not be related to joinpoint at all. apparently django does this, and it would let us define criterion for multiple overlapping paths, such as q.filter_by(['a', 'b, 'c'], d=x).filter_by (['a', 'b', 'e'], d=x). thats something that you cant do with the straight join() alone (but of course you can do with explicit aliases and filter()/select_from()). - the auto find me a property behavior is gone. not sure if I want to remove it from select_by() and friends, i think it should probably remain in those in a deprecated state. - ClauseElement support would be removed from filter_by(). you can just use filter() for those. the older _by() methods, which i want to deprecate, would be left alone for backwards compatibility. - i want to deprecate all the criterion methods that are not filter, i.e. all the selects and most of the gets (except straight get()). selecting from a full statement we can do with query.from_statement (select statement), the argument of which is a select() or a string. deprecating select() and select_by() is to create a single simple interface to query based on the more flexible filter(). but it does mean a bit more typing in many cases. I would hope everyone is OK with that. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
what about adding a docopy=True (or dont_copy=False) to all methods that could be both copy_generative and modify-in-place? via some generic self=self.copy_if_required() func? Then one can choose at which point to split+copy well if you have switches that are dynamically modifying the central paradigm of the API, that suggests you arent too sure about that API. well... sooner or later u'll have mostly generative methods (which is, copying/cloning+extras), and then someone may need a faster modify-in-place version. say, by a special (metaclass or decorating) wrapper i could make a cloning version from any inplace one; but i cannot do it viceversa - if u make the cloning one the base. This wrapper/decorator can go in SA interfaces if u wish - where there is alternative. For some methods the cloning version will be official, for others - the inplace one. another way is the command pattern, cloning some very_cheap object, but i dont think it is very usable here. also that approach doesnt really solve this problem since the goal is to execute just one query with many features combined. it is not about solving some particular problem, it's just a generic way to modify/extend the API without really changing the look of it. so u dont end with manualy made filter_inplace() and filter_clone() one day.. Actualy inspired by the other thread about the inplace append_whereclause(). ciao svil --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Jun 1, 2007, at 12:39 PM, Gaetan de Menten wrote: This enables things like so (see attached elixir-based example for more): A.query().filter_by_via('b', name='b2').filter_by_via('c', name='c2') To Michael: I'm ready to document that myself, but I just don't want to do it for nothing in the unlikely event you'd agree with me that this join_point thing should be removed. Another thing which I find ugly in the query class is the whole idea of using a locate property method. It's awfully unreliable: if two properties lead to different classes both having a property with the same name, which one is used? I'd like if people at least had a way to specify the full path leading to the desired property (and still use a concise keyword syntax and not full blown where clauses). well this is all related. id like to take out the auto-descending thing out of filter_by(), *_by(), and join(). but if you take out the joinpoint, *and* the auto-descend thing which is already ambiguous, filter_by and friends become not very useful. like this would not produce the expected results at all: A.foo - B.bar - C.lala query(A).join(['foo', 'bar']).filter_by(lala=5) So id propose something like what you did above, but not use a string, just use the class, and have it as the first optional positional arg to all the _by()s query(A).join(['foo', 'bar']).filter_by(C, lala=5) and we can even bring back a modified version auto-descend in that case: query(A).filter_by(C, lala=5) since above its not ambiguous. another thing i have always wanted to do, is take the ClauseElement stuff out of the _by() methods. I know people put ClauseElements in those but that was because there used to not be a way to mix ClauseElements with keywords...now there is, just call filter() and filter_by() separately. if you agree with all that, lets just put it straight into 0.4. i think we should get a little dramatic here, make the above filtering changes, and also whack all the redundant methods: that is, get_by (), select_by(), select(), selectfirst(), selectone(),selectfirst_by (), etc etcthey get replaced with filter()/filter_by() - list()/ scalar()/one(). this would also eliminate most of the confusion people have from the multiple select() functions produced by different APIs. by whack i havent decided if i mean, whack, or deprecate and remove from main docs. Id go with the latter, but a lot of other tutorial sites and such which have sprang up would have to go with me here and make similar changes to their docselse people will keep using the old methods. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Jun 1, 2007, at 1:24 PM, Michael Bayer wrote: and we can even bring back a modified version auto-descend in that case: query(A).filter_by(C, lala=5) since above its not ambiguous. actually, scratch that. C can be related to multiple times. also its ambigious if you want autojoin to kick in or to use joins that are already within the from clause. so i modify my proposal to just whack auto-join period. filter_by(class, **kwargs) will strictly create criterion against class's table using the **kwargs. to make the joins you use join(). no joinpoint is set up. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
OK, irc continues, now i see what youre getting at, its this: query.filter_by(['a', 'b', 'c'], foo=bar) query.filter_by('c', foo=bar) i didnt pick up on the list part from the example. that feature specifically starts to look like a django join. the 'join list' at the front is contained within the scope of the filter_by. this implies that the joins should be constructed from aliases so that similar filter_by() calls can be used repeatedly, and also that they wont conflict with any existing joins. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Friday 01 June 2007 21:38:15 Michael Bayer wrote: On Jun 1, 2007, at 1:24 PM, Michael Bayer wrote: and we can even bring back a modified version auto-descend in that case: query(A).filter_by(C, lala=5) since above its not ambiguous. actually, scratch that. C can be related to multiple times. also its ambigious if you want autojoin to kick in or to use joins that are already within the from clause. so i modify my proposal to just whack auto-join period. heh, if i remember how whole-heartly u defended this autodescend thing some months ago... IMO u can have some configuration arg like autodescendjoin =False by default (or True to have it compatible with old code/lazy programmers) -- IF u want to somehow keep that unreliable traversal-guess at all. Another herotic idea: look around the overriding userclass' __init__ method and why that is needed. This seems to me to be somehow connected to assignmapper, it's again about autoguessing mappers/sessions. IMO these notions (mapping, session-attaching, etc similar attaching of user-klas/obj to some DB/ORM-related thing) can be separated and have a possibility to make any combination of those, not just one hardcoded. e.g. the same way u can have now assignmapper vs not have one, u should have auto-mapper-compilation vs non-auto. and more IMO, i think all these auto-guessing things in SA (and u have many,many of them, and u like them) are _okay_ as far as there is a way to disable them and require/specify all explicitly. Whether the default would be the (easy) autoguess or not, is irrelevant here. did u get my point? ciao svil --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
On Jun 1, 2007, at 5:33 PM, [EMAIL PROTECTED] wrote: heh, if i remember how whole-heartly u defended this autodescend thing some months ago... we didnt have generative behavior built into query so there was no way to conveniently get at an attribute based on a join. and more IMO, i think all these auto-guessing things in SA (and u have many,many of them, and u like them) are _okay_ as far as there is a way to disable them and require/specify all explicitly. i cant think of other places in SA that are literally guessing. we have a lot of assuming as well as defaults. these are not guesses because they are deterministic. a guess means you have more than one choice, and you pick one - randomly, or based on other things that were random (like dictionary ordering). it cant be predicted. if you map a relation from class A to B, we assume the join condition is based on the foreign keys between A and B's table. if I say A.join(B), the only possible way to join them unless explicitly stated is along their foreign keys (or I suppose you could say their column names, but that would be silly). thats not a guess...it will do the same thing every time. another example of a default is if you map a relation from A-A, it places the foreign key on the right side of the relation by default unless you specify remote side. thats also not a guess. the topological sort that occurs during a flush - there is a degree of non-determinism there to the extent that more than one ordering exists for a given set of dependencies. but it *is* deterministic that the resulting ordering will be correct. theres no guess there, just that the specific ordering is just undefined, just like for a dictionary. if there were many, many guesses going on, we'd have many, many broken applications. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: [PATCH] filter_by_via
plus *another* option to think about here, which was actually my first (suppressed) instinct, but now i just saw that Hibernate sort of does this, is to *keep* the joinpoint in and just have the join function reset the joinpoint on each invocation. so, session.query(User).join(['orders', 'items']).filter_by (item_name='foo').join(['addresses']).filter_by (email_address='[EMAIL PROTECTED]').list() at the moment, this seems intuitive to me. but i dont know if itll stay that way. i do like that each method has a single type of argument, as opposed to filter_by(qualifier, **kwargs). --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---