On 2/26/07, Russell Keith-Magee <[EMAIL PROTECTED]> wrote: > > On 2/25/07, Malcolm Tredinnick <[EMAIL PROTECTED]> wrote: > > > > What would the new (QuerySet) world order look like > > ---------------------------------------------------- > > What I propose to do is to split out the SQL construction from the body > > of QuerySet and make it into a separate class. This class (let's call it > > Query, for simplicity) would end up being a "query" attribute on > > QuerySets and it's __str__ function would return the appropriate SQL > > statement. > > Broadly speaking, +1. When I last gave serious thought to aggregates, > I was starting to have similar ideas on the need for a QuerySet > refactor. Nice to know I'm not completely out on my own. > > Of course, the devil is in the detail, and there are some interesting > edge cases where WHERE, HAVING and GROUP BY intersect, but if you're > willing/able to come up with a first draft, I'm happy to throw my > weight into poking holes in it. :-)
I went for a skiing trip last week, since there was no snow, I gave the QuerySet a try: I implemented a very simple approach, using Query as a class representing the SQL statement ( I didn't actually deal with querysets, just the SQL) I use objects class Model - represents a model/table, can be joined with other model via a path ( 'some__related__lookup'.split( '__' ) ), has a reference to query class Field - has a reference to Model instance so that it can get its alias (one django model can be used twice in one query), has a reference to query operator - a simple dictionary containing functions producing SQL snippets for expressions, for example: { 'lt' : lambda x,y: '%s < %s' % (x, y), }, more operators can be registered at runtime (custom SQL operators) class Q - represents generic condition, can be ORed and ANDed, can be used as WHILE or as HAVING clauses, have the filter( **kwargs ) method, has a reference to query class Query - contains list of Fields to select, Models to select from, and mainly encapsulates all lookup operations, so you can call self.query.lookup_path( some_path ) and it will return a correct Field instance representing the field and add the necessary joins and where conditions to the query in the background -- this is the main method where most work will be done, to demonstrate, this is how a working order_by() method looks: def order_by( self, *args ): """ '-field', 'related__field__to__order__by' """ self.order_by = [] for field in args: if field.startswith( '-' ): order = 'DESC' field = field[1:] else: order = 'ASC' field = self.lookup_path( field.split( '__' ) ) self.order_by.append( ( field, order, ) ) rendering the order by: if self.order_by: output.append( 'ORDER BY' ) output.append( ', '.join( '%s %s' % ( f.alias, order ) for f, order in self.order_by ) ) the other thing this approach will bring is that by overriding Query's __str__() method, you can modify everything - nothing is stored in text form, everything is normalized and only when putting the SQL code together is it evaluated. so we could even move this (or parts of it) to the backend and thus work with the special features of the individual engines. Or just allow users to supply their own Query class. only the Q object representing the condition is rendered separately via the operators. I will try and clean up the code today and post it along with some examples. Its just a proof of concept, so it can only deal with simple forward foreign keys, but I think this approach might just work. start the poking ;) > > > Things I think become easier this way > > ------------------------------------- > > - aggregates and other computed output columns > > - custom fragments in portions of a query (as opposed to writing > > a whole query for the database) > > - adding new query types (GIS?) > > - different database syntax (LIMIT/OFFSET in both MS SQL Server > > and Oracle) > > > > I don't know of any announced plans/wishes that affect QuerySets that > > would become more difficult under this change, so please sing out if you > > know of any. > > That's a pretty good list. There might be a few others, but these are > the big ones I am aware of. > > Yours, > Russ Magee %-) > > > > -- Honza Kr�l E-Mail: [EMAIL PROTECTED] ICQ#: 107471613 Phone: +420 606 678585 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-developers?hl=en -~----------~----~----~----~------~----~------~--~---