I like it all! Arnar
On 3/10/07, Michael Bayer <[EMAIL PROTECTED]> wrote: > > 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 -~----------~----~----~----~------~----~------~--~---