On Feb 27, 2009, at 3:10 PM, Ben Zealley wrote:
Hi all,
I've got a requirement that seems like it should be fairly
straightforward, but my own attempts to work out the necessary code
have just become more and more contrived, and still don't work :( so
I'm hoping someone more familiar with SQLA's design can suggest a
better approach!
Background:
I have a function which creates a query 'q' on a mapped class (Foo),
then applies one or more filter criteria, before finally executing the
query and returning a list of results. In general the individual
criteria might apply to any attribute of the mapped class; I have the
attribute name (at this point anyway) as a string 'attr'. The criteria
may also use various modes; I convert these into an SQL operator
'sqlop' (so for example 'exact' becomes '=', 'exclude' becomes ' NOT
LIKE ', etc.)
So the generative filter() call is basically just:
q = q.filter(attr + sqlop + :val).params(val=test)
you might want to look into a functional approach here, i.e.
sqlop(MyClass.attr, test). More extensible, less typing (no need for
params()), etc.. For example:
from operator import eq
def exact(x, y):
return eq(x,y)
You can also create custom comparison operations on any mapped
attribute using the comparator argument to column_property() or
relation().
http://www.sqlalchemy.org/docs/05/mappers.html#id2
note that you can add any kind of method to a Comparator in the most
recent release of SQLAlchemy (such as your exact() method).
Now the problem:
That all works fine until I want to filter on attributes that are
relational. Say Foo has a one-to-many or many-to-one relation to Bar
('rBar'). When I try to filter Foo on rBar, I want those Foos whose
rBar collection includes at least one Bar whose Title attribute
matches the criterion if it's one-to-many, or those Foos whose rBar
points to a Bar whose Title matches the criterion if it's many-to-
one.
SQLA has operators has() and any() which support this directly. the
joins are created via correlation within an EXISTS clause.
http://www.sqlalchemy.org/docs/05/ormtutorial.html#using-exists
Huge bonus points if your solution also works for a self-referential
many-to-many relation that uses an association table (there are two,
'rFooPrecedes' and 'rFooFollows', which are Foo-Foo links via the
FooPrecedence mapped class; here I'd want to filter based on the
titles of the attached Foos, not on the titles of the FooPrecedence
entries that link them).
has() and any() all handle this automatically.
--~--~-~--~~~---~--~~
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
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---