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 [email protected]
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
-~----------~----~----~----~------~----~------~--~---