[sqlalchemy] Re: Generative style on SQL-API layer
on a side note, here or for the query(), once i add .order_by() and similar, will be a possibility to remove/cancel them? e.g. .order_by(None) - similar to .join(None)? or should i keep a copy at the point before adding .order_by()? e.g. i want: q1 = query.filter( ...).order_by(z)#the final most used query ... q2 = q1.order_by(None)#used sometimes e.g. for count vs i could do: q0 = query.filter( ...) #saved q1 = q0.clone().order_by(z) #the final most used query ... q2 = q0 #used sometimes e.g. for count i know this above looks very similar, but in overall workflow, q1 and q2 can be separated very far away. I want to wake this thread up again. can we get some arguments pro/ con to converting select() to work in a generative style ? --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
svilen ha scritto: on a side note, here or for the query(), once i add .order_by() and similar, will be a possibility to remove/cancel them? e.g. .order_by(None) - similar to .join(None)? or should i keep a copy at the point before adding .order_by()? e.g. i want: q1 = query.filter( ...).order_by(z)#the final most used query ... q2 = q1.order_by(None) #used sometimes e.g. for count vs i could do: q0 = query.filter( ...) #saved q1 = q0.clone().order_by(z) #the final most used query ... q2 = q0 #used sometimes e.g. for count and why not q = query.filter(...) q1 = q.order_by(z) ... q2 = q ?? --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
svilen ha scritto: on a side note, here or for the query(), once i add .order_by() and similar, will be a possibility to remove/cancel them? e.g. .order_by(None) - similar to .join(None)? or should i keep a copy at the point before adding .order_by()? e.g. i want: q1 = query.filter( ...).order_by(z)#the final most used query ... q2 = q1.order_by(None)#used sometimes e.g. for count vs i could do: q0 = query.filter( ...) #saved q1 = q0.clone().order_by(z) #the final most used query ... q2 = q0 #used sometimes e.g. for count and why not q = query.filter(...) q1 = q.order_by(z) ... q2 = q ?? because q1 with the order is _the_ query, made at point A somewhen, and stored there as a construct; much later at some point B i need to use that query but without the ordering - now i have to keep 2 copies of the query, w/ and w/out order. And this strip-the-ordering could be generic, applicable to any query... --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
svilen ha scritto: because q1 with the order is _the_ query, made at point A somewhen, and stored there as a construct; much later at some point B i need to use that query but without the ordering - now i have to keep 2 copies of the query, w/ and w/out order. And this strip-the-ordering could be generic, applicable to any query... Basically you're asking for that to gain some performance on q2.execute(), and at the same time you want to avoid littering your function's namespace. Ok, I understand. I find the API is cleaner without that feature, but I am nobody here :-) --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
Beyond the API littering, there may be instances where it is difficult or impossible to remove a query attribute, because adding the attribute caused a join calculation or reordered parenthesis, or whatever. The second pattern is better, e.g. save a copy, rather than mucking things up with removal code. One of the aims here is to simplify the API, and IMO adding removal code works against that. On 6/6/07, Marco Mariani [EMAIL PROTECTED] wrote: svilen ha scritto: because q1 with the order is _the_ query, made at point A somewhen, and stored there as a construct; much later at some point B i need to use that query but without the ordering - now i have to keep 2 copies of the query, w/ and w/out order. And this strip-the-ordering could be generic, applicable to any query... Basically you're asking for that to gain some performance on q2.execute(), and at the same time you want to avoid littering your function's namespace. Ok, I understand. I find the API is cleaner without that feature, but I am nobody here :-) --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
it's not about littering API / namespaces or not, but if u percieve it just as such... nevermind. i admit that undoing some change can be difficult or just impossible in certain cases. So i'll do a sort of command pattern then, keeping intermediate queries. Forget that i asked. Beyond the API littering, there may be instances where it is difficult or impossible to remove a query attribute, because adding the attribute caused a join calculation or reordered parenthesis, or whatever. The second pattern is better, e.g. save a copy, rather than mucking things up with removal code. One of the aims here is to simplify the API, and IMO adding removal code works against that. On 6/6/07, Marco Mariani [EMAIL PROTECTED] wrote: svilen ha scritto: because q1 with the order is _the_ query, made at point A somewhen, and stored there as a construct; much later at some point B i need to use that query but without the ordering - now i have to keep 2 copies of the query, w/ and w/out order. And this strip-the-ordering could be generic, applicable to any query... Basically you're asking for that to gain some performance on q2.execute(), and at the same time you want to avoid littering your function's namespace. Ok, I understand. I find the API is cleaner without that feature, but I am nobody here :-) --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
On Jun 5, 2007, at 10:30 PM, Mike Orr wrote: I do think .append_whereclause should be changed to .append_to_where. A SQL statement can have only one WHERE clause; what you're actually appending is an AND operand. .append_to_where seems to get that across better than .append_whereclause or .append_where. The word clause is superfluous because all parts of a SQL statement are called clauses. I know phrases like append_to_where are more correct, but its a lot of typing. I had in mind just where(). i dont think people trip over the meaning of multiple where() statements. --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
On Jun 6, 8:32 am, Michael Bayer [EMAIL PROTECTED] wrote: On Jun 5, 2007, at 10:30 PM, Mike Orr wrote: I do think .append_whereclause should be changed to .append_to_where. A SQL statement can have only one WHERE clause; what you're actually appending is an AND operand. .append_to_where seems to get that across better than .append_whereclause or .append_where. The word clause is superfluous because all parts of a SQL statement are called clauses. I know phrases like append_to_where are more correct, but its a lot of typing. I had in mind just where(). i dont think people trip over the meaning of multiple where() statements. +1 for where() also for group_by() and having(), no? ...see: http://www.mail-archive.com/[EMAIL PROTECTED]/msg03449.html --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
Yeah, I'm +1 on .where() as well. On 6/6/07, Michael Bayer [EMAIL PROTECTED] wrote: On Jun 5, 2007, at 10:30 PM, Mike Orr wrote: I do think .append_whereclause should be changed to .append_to_where. A SQL statement can have only one WHERE clause; what you're actually appending is an AND operand. .append_to_where seems to get that across better than .append_whereclause or .append_where. The word clause is superfluous because all parts of a SQL statement are called clauses. I know phrases like append_to_where are more correct, but its a lot of typing. I had in mind just where(). i dont think people trip over the meaning of multiple where() statements. --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
just to note, I am leaning towards very simple generative method names for all the things we need, where(), having(), order_by(), group_by(), distinct(), etc. I am going to have it do copy on generate by default. the copy operation itself will be pretty quick, working the way I have it working with Query now in the 0.4 branch, i.e. its just q= Query.__new__() then a q.__dict__ = self.__dict__.copy(). the deep copy operations occur upon the generative methods...i.e. instead of saying q.where_clauses.append(clause), it does q.where_clauses =q.where_clauses + [clause]...so you localize the more expensive collection copying operations to that of one per each generative method. I will probably have a little flag generative=False which will just be mentioned in the docstring and thats it (i.e., im not going to push the usage of that flag, it wont usually be needed). to make a select statement all at once, you will still be able to do what we do now in most cases, just using select([columns], whereclause, **otherargs). one thing i like about rebuilding select this way is that i will be able to rewrite its internals to halfway make sense...its a little overgrown in there right now. --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
.where() is OK. On 6/6/07, svilen [EMAIL PROTECTED] wrote: q2 = q1.order_by(None)#used sometimes e.g. for count This would be useful. If a second .order_by can replace the ordering (as opposed to appending to it), I don't see why it would be difficult to delete it. .order_by shouldn't add another join condition, and even if it did and that can't be deleted, so what? If the use wanted an absolutely clean query, they should have constructed it cleanly in the first place. However, I like the way Query.count() ignores the order_by.This allows my functions to return a Query, and the caller can call .list(), .count(), selectone(), or another aggregate method as they wish, and it does the right thing. I'm concerned that we're building an elaborate API that is kinda like Query but not identical. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
On 6/6/07, Michael Bayer [EMAIL PROTECTED] wrote: just to note, I am leaning towards very simple generative method names for all the things we need, where(), having(), order_by(), group_by(), distinct(), etc. I am going to have it do copy on generate by default. If a generative default can be efficient, it would avoid the dilemma of Generative or not?, while also being parallel with Query. Otherwise, returning 'self' would be fine, and I promise to look the other way. :) Then I could do: q.order_by(...) instead of q = q.order_by(...) While those who prefer the latter can do that, and if you really need a copy: q = q.clone().order_by(...) Keep in mind that modifying the query is much more frequent than copying it. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
While those who prefer the latter can do that, and if you really need a copy: q = q.clone().order_by(...) explicit is better than implicit is one rule that may apply here. Not that i enslave myself with those rules but they do make sense in most cases in the long-run. Michael, u hold the bread, u hold the knife, the choice is yours (-;) 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: Generative style on SQL-API layer
I want to wake this thread up again. can we get some arguments pro/ con to converting select() to work in a generative style ? generative means either just the first, or both of these two things: - methods like append_whereclause() return a select object with which to call further genreative methods. this is a good thing because you can say select.append_whereclause().order_by().group_by() etc. - the select object you get back is a *copy* of the object which you called. advantages include: * is more Pythonic (not sure why this is, Mike Orr said so, would like more exposition) * you might want to reuse the original object differently (is that such a common pattern ? seems weird to me..more exposition here too) * would be consistent with orm's Query() object which has made its choice on the copy side of things disadvantages: * inconsistent ? the select() function also takes a whole assortment of arguments which can construct the entire instance at once. the generative API already adds more than one way to do it. * performance. an application that builds queries on the fly and executes them will be generating many copies of a select(), most of which are thrown away. if the ORM uses these approaches as well, latency is added throughout. for performance considerations, select() can implement both a generative and a non-generative API (in fact it will always have a non- generative API for adding modifiers anyway, just that its marked with underscores as semi-private). this can be specified either via constructor argument or by a different set of methods that are non- generative. however, either of these ideas complicate the select() object. we might want to go with just a flag generative=False that quietly allows an application to optimize itself. or we might want to say, build the select object all at once if the overhead of generativeness is to be avoided. --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
hmm, actualy, in such select.append_whereclause().order_by().group_by().whatever1 ().whatever2()... What is the point of anything except the very first funccall to be generative? the direct results are thrown away, and the copies are used - whyfore? (i guess this applies to query() as well...) isn't it better to just have s2 = select1.clone().order_by().group_by().whatever1().whatever2() so the original select1 is left intact, and s2 is a development of a clone of s1. -- before figuring the above, i wrote this below, but now it seems less important: for me the main advantage is that it will match query's general behaviour / footprint - query() being ORM's way for doing .select's. as long as i have both generative/copying and non-generative (inplace-modify) alternatives, it seems ok. whether the default behaivour to be the generative or the non-generative - this argument can last forever, so just choose one (the easier/less surprising), and provide 2 methods for those i hate to write long keyword-args. same as for ORM's query(). u can even have the default choice as class-variable, But afaik u almost have no such class-level defaults, so your choice. heh, u can have some current_generativeness flag which can be set or unset by a func. hence: s1 = select.where(x).order_by(y) s2 = s1.set_generative().group_by(z).whatever() will all the order_by() etc be generative only, or they will have that choice flag too? or will follow the whatever choice has already been made? svil I want to wake this thread up again. can we get some arguments pro/ con to converting select() to work in a generative style ? generative means either just the first, or both of these two things: - methods like append_whereclause() return a select object with which to call further genreative methods. this is a good thing because you can say select.append_whereclause().order_by().group_by() etc. - the select object you get back is a *copy* of the object which you called. advantages include: * is more Pythonic (not sure why this is, Mike Orr said so, would like more exposition) * you might want to reuse the original object differently (is that such a common pattern ? seems weird to me..more exposition here too) * would be consistent with orm's Query() object which has made its choice on the copy side of things disadvantages: * inconsistent ? the select() function also takes a whole assortment of arguments which can construct the entire instance at once. the generative API already adds more than one way to do it. * performance. an application that builds queries on the fly and executes them will be generating many copies of a select(), most of which are thrown away. if the ORM uses these approaches as well, latency is added throughout. for performance considerations, select() can implement both a generative and a non-generative API (in fact it will always have a non- generative API for adding modifiers anyway, just that its marked with underscores as semi-private). this can be specified either via constructor argument or by a different set of methods that are non- generative. however, either of these ideas complicate the select() object. we might want to go with just a flag generative=False that quietly allows an application to optimize itself. or we might want to say, build the select object all at once if the overhead of generativeness is to be avoided. --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
Michael Bayer wrote: I want to wake this thread up again. can we get some arguments pro/ con to converting select() to work in a generative style ? generative means either just the first, or both of these two things: - methods like append_whereclause() return a select object with which to call further genreative methods. this is a good thing because you can say select.append_whereclause().order_by().group_by() etc. I'm for returning self rather then a copy, because needing a copy in my experience thus far with SA has been the exception. What's wrong with s1 = select.copy() to explicitly get a copy. Are you going to do the the select.where() change :-) - the select object you get back is a *copy* of the object which you called. advantages include: * is more Pythonic (not sure why this is, Mike Orr said so, would like more exposition) * you might want to reuse the original object differently (is that such a common pattern ? seems weird to me..more exposition here too) * would be consistent with orm's Query() object which has made its choice on the copy side of things disadvantages: * inconsistent ? the select() function also takes a whole assortment of arguments which can construct the entire instance at once. the generative API already adds more than one way to do it. * performance. an application that builds queries on the fly and executes them will be generating many copies of a select(), most of which are thrown away. if the ORM uses these approaches as well, latency is added throughout. for performance considerations, select() can implement both a generative and a non-generative API (in fact it will always have a non- generative API for adding modifiers anyway, just that its marked with underscores as semi-private). this can be specified either via constructor argument or by a different set of methods that are non- generative. however, either of these ideas complicate the select() object. we might want to go with just a flag generative=False that quietly allows an application to optimize itself. or we might want to say, build the select object all at once if the overhead of generativeness is to be avoided. --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
On 6/5/07, Michael Bayer [EMAIL PROTECTED] wrote: I want to wake this thread up again. can we get some arguments pro/ con to converting select() to work in a generative style ? generative means either just the first, or both of these two things: - methods like append_whereclause() return a select object with which to call further genreative methods. this is a good thing because you can say select.append_whereclause().order_by().group_by() etc. I don't think it's necessary to allow method chaining just because Query does. One of our objectives is to make SQL select and ORM query more distinct so they're not confused, especially if ORM .select() is going to be sticking around for a while. However, I expect there will be overwhelming pressure to add this syntax so we might as well assume it's inevitable. I do think .append_whereclause should be changed to .append_to_where. A SQL statement can have only one WHERE clause; what you're actually appending is an AND operand. .append_to_where seems to get that across better than .append_whereclause or .append_where. The word clause is superfluous because all parts of a SQL statement are called clauses. - the select object you get back is a *copy* of the object which you called. advantages include: * is more Pythonic (not sure why this is, Mike Orr said so, would like more exposition) it's just bad style for a method to return self. Perl classes do it as a pattern, while Python libraries have always avoided it. Python methods normally return None, a new immutable object, or a calculated value. Although as I said before, maybe it's not that big a deal for this special case where you have to call several methods all at once in order to get a complete SQL statement. * you might want to reuse the original object differently (is that such a common pattern ? seems weird to me..more exposition here too) It *is* useful to prebuild part of a query, then let the caller modify it. I went to this pattern: def list_incidents(top_only): q = table1.select(table1.c.is_public) if top_only: q.append_whereclause(table1.c.is_top) return q Then the caller can add more restrictions or an order_by. Because every method modifies the query in place, I have to get a fresh select by calling the factory again if I want to query the same table a different way. That's not a big deal, but that is the cost of non-generative selects. Adding a .clone() call would be convenient, though for me it's just as easy to call my factory function again. * would be consistent with orm's Query() object which has made its choice on the copy side of things Well, can we go all the way and duplicate Query's API completely? Then there would be One Way to do it. I suppose I should say something more about the pros/cons of .select method chaining, but I've got a headache today so I can't think too hard. -- Mike Orr [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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: Generative style on SQL-API layer
On May 9, 2007, at 4:08 PM, Rick Morrison wrote: Hey Mike, I've really gotten to like the generative style of query building that the ORM layer uses, and I find myself developing a number of patterns that use that style to good advantage. Today I found myself struggling with a query in the low-level SQL- API layer that the generative approach would make really easy -- is there a way to get the same kind of generative effect in the lower layers? Right now I'm kind of hacking something that uses copy.copy() on the select(), and that surprisingly seems to work, but makes me think there must be a better way. yeah i really should have just imitated Hibernate more closely when i started this thing. theres no technical reason generativeness couldnt be applied to ClauseElements except for potential API messiness. we do have methods on select() that modify it, such as append_whereclause(), order_by(), and such...if they just returned self, then you could act more generatively with it, i.e. select(...).append_whereclause ().order_by()..etc. then again, true generativeness would have simpler method names like just where(), from(), etc. and I suppose those arent a big deal to add. like with Query, im not sure what the advantage is to the select() being actually copied though i guess thats the safer approach (but notably is not how Hibernate's Criterion object works; you get the same one back each time). so the do we actually copy is a big decision to make, and unfortunately Query has made its decision on the yes side so i think we might have to lean that way for consistency. on a related note we have a ticket in place to allow select() to be copyable, which is not a big deal but i want there to be some nice tests set up for that since a select has a lot of elements that need to be faithfully copied over. we are close to a 0.4 so perhaps that would be a good time for some slight API change on select(). also it seems like select() is really the only construct that really could use generativeness...other constructs like joins, aliases, etc., already have methods to create new objects from them, but as far as mutating operations it seems select() is the only real candidate (would you want generativeness on other constructs, like CASE, boolean operators, 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 -~--~~~~--~~--~--~---