Shahms King wrote:
> Currently, SQLObject.select() can be called in a number of ways,
> including taking arbitrary SQL for a where clause or using the '.q'
> object to build an expression. This flexibility is wonderful, but the
> '.q' object does present some difficulty with joins as one must manually
> specify the 'Child.q.parentID==Parent.q.id' parameter. It also means
> that using raw SQL is necessary for queries involving many-to-many
> joins, as the "table" is never exposed. It should be possible to simply
> say "Child.q.parent.name == 'somestring'" and have the '.q' object
> determine the join. Conversely, one should be able to say
> "Parent.q.children.name == 'somestring'" and have the reverse join work
> as well. Once this is done the many-to-many joins can also be used in
> query expressions.
SQLRelatedJoin addresses some of this, since you can do:
And SQLMultipleJoin offers some similar advantages. Potentially
ForeignKey could also be extended in this way, so that
'Child.q.parent.name == "somestring"' could become (child.parent_id =
parent.id AND parent.name = 'somestring') using a little cleverness (so
that Child.q.parent would actually be a wrapper that would look like
Parent.q, except add the join to the query that results).
> In order to maintain backwards compatibility with the current .q and
> provide enough flexibility to allow the same or similar methods to be
> applied to generic (or suitably decorated) iterators, I propose that the
> clause parameter of select() be extended to allow passing a callable
> taking a single 'query source' parameter and returning an expression.
> For example:
> Child.select(lambda c: c.parent.name == "somestring")
> Parent.select(lambda p: p.children.name == "somestring")
I think this is difficult, since it requires decompiling the expression.
That's not impossible -- RuleDispatch (part of PEAK) does this (except
using strings instead of lambdas), and with much the same purpose. But
though possible, it doesn't seem very easy. And the time and scope of
evaluation can be a little more confusing -- is the expression
(partially) evaluated at the time .select() is called? Or when it is
used? Closures handle some of this, but it can still lead to confusion.
Though I suppose it is similar to LINQ in this way.
I think most of what you want is possible without resorting to lambdas.
I wouldn't really want to take on the task (at least myself) of doing
that kind of decompiling, but if that functionality was available in a
stable library it might be easier to approach. Even better if these
kind of expressions were part Python itself. (If you were decompiling
expressions, you also wouldn't need to use 'AND', you could use plain
Ian Bicking | ianb@... | http://blog.ianbicking.org