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
-~----------~----~----~----~------~----~------~--~---

Reply via email to