Well initial response to this post has been overwhelmingly low, but thats fine with me. After trying to tackle this today, I realized that I actually didnt want to add a brand new query object and go through a painful deprecation procedure again and all that...and I also observed that the notion of a query being against a single entity is pretty important..things like get(), load() and all that dont make much sense for multiple entities. Also, all the things Ive wanted to do are not actually that hard as we already have code to do most of it.
So I did not add any new classes or modules, no new methods on session, I didnt go with my modified "generative" approach (its just like it always was) and changed absolutely nothing about Query thats already there (well one little thing i dont think anyone was using). But I added a whole lot of new methods to Query, essentially everything SelectResults was able to do. I was concerned about having just too much crap on Query but i think it turned out fine. Plus I added a little bit of hibernate-like capabilities to query multiple entities and extra columns too. So...with that, heres what Query can do now. First of all, the same stuff that youve always used is just like it always was: query.select_by() query.select() query.get() query.count() query.select_by_XXX().... A couple of methods that Ive never liked because they are klunky, are still there anyway: query.join_to() query.join_via() As it stands, Query has two "generative" methods already (which also i had to fix a little bit since "generative"-ness would wipe out what was previously there). these return for you a new Query with modifications to its state: query.options() query.with_lockmode() So we add a lot of new generative methods taken from SelectResults, all of which return a brand new Query. the things you add here will also take effect on subsequent calls to the regular select(), count(), select_by(), etc: query.filter() - adds criterion query.filter_by() - ditto query.join() - joins to a property name, or a list query.outerjoin() query.order_by() query.group_by() query.distinct() - applies DISTINCT query.offset() query.limit() query[3:5] -> applies offset 3, limit 2 like SelectResults, we have some "executors" - query.list() list(query) or just call query.select(), selectfirst(), selectone(), etc. to execute whatever has been built up. the aggregates, which take a Column (not sure how popular these are): query.avg() query.sum() .. and others So a generative example, including "join" which im really excited about. join can act either like "join_to()": q = session.query(Person).filter_by(people.c.name.like('%2')).join('status').filter_by(name="active") print q.list() or like "join_via" (which is more deterministic), if you send a list: l = q.filter(orderitems.c.item_name=='item 4').join(['orders', 'items']).list() and then, some brand new stuff - better support for "querying more than one thing at a time". the instances() method, which was able to take a list of *mappers, now returns the results the way the docs say they do, as a list of tuples, each tuple having an entry for each mapper. additionally, when that option is used, the "uniquing" of the result is turned off - this so that the results you get back correspond to the rows that went in. and, you can stick arbitrary columns, not just mappers, in the list too...it will just pull them from the row. in addition to the changes on instances(), you can add extra entities/ columns to the compilation as well: query.add_entity() - adds columns to the select criterion query.add_column() - adds columns to the select criterion so what can we do with this ? things like, query an entity and an aggregate function at the same time: q = sess.query(User) q = q.group_by([c for c in users.c]).outerjoin('addresses').add_column(func.count(addresses.c.address_id).label('count')) l = q.list() which will return for you a list of tuples: [ (user1, 3), (user2, 5), (user3, 0), ..etc ] note the "label" is needed right now for a function, it makes it possible for Query to target the column correctly. another one from the unit tests. the "users" table has users 7, 8, 9 in it. the "addresses" table has addresses 1, 2, 3, 4. user #7 refereces address #1, user #8 references addresses 2, 3 and 4. (user7, user8, user9) = sess.query(User).select() (address1, address2, address3, address4) = sess.query(Address).select() q = sess.query(User) q = q.add_entity(Address).outerjoin('addresses') l = q.list() assert l == [ (user7, address1), (user8, address2), (user8, address3), (user8, address4), (user9, None) ] this is how the "non-uniquing" works. anyway, its all in the trunk, feel free to screw around. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---