supply a pre-built comparator on associationproxy instead of requiring homegrown

Issue #1372 resolved
Former user created an issue

Let's consider the example given in the documentation. One can do:

s.query(User).filter(User.user_keywords.contains(user_keyword))

but he can't do:

s.query(User).filter(User.keywords.contains(keyword))

because:

AttributeError: 'AssociationProxy' object has no attribute 'contains'

That's why, when I use the association_proxy pattern, I also add another view only relation between the two referenced objects (in this case User and Keyword), using the secondary table. I use this relation for selecting, and I use the association_proxy relation for inserting...

This duplication is annoying. I don't know if it's possible to solve the problem, but I want to be able to do:

s.query(User).filter(User.keywords.contains(keyword))

kobipe3@gmail.com

Comments (9)

  1. Former user Account Deleted

    I wanted to use the has and any functions on associationproxies, and didn't know about about comparable_property, so I added this to AssociationProxy:

    import sqlalchemy.exceptions as sa_exc
    
    #snip
    
        def any(self, criterion=None, **kwargs):
            if self._target_is_scalar():
                raise sa_exc.InvalidRequestError("'any()' not implemented for scalar attributes. Use has().")
            return self._get_property().comparator.any(getattr(self.target_class, self.value_attr).has(criterion, **kwargs))
    
        def has(self, criterion=None, **kwargs):
            if not self._target_is_scalar():
                raise sa_exc.InvalidRequestError("'has()' not implemented for collections.  Use any().")
            return self._get_property().comparator.has(getattr(self.target_class, self.value_attr).has(criterion, **kwargs))
    

    I'll try using a comparable_property instead now, but if it's possible to implement a general solution for AssociationProxy, I'd be willing to try to figure out the other Comparator functions.

  2. Former user Account Deleted

    Here's a patch against 26edef4f2483f68d6a527684a6d0aed37554534d that adds proxying of .any(), .has(), .contains(), ==, and != to association_proxies. Lots of tests are included.

    Any thoughts on whether or not this implementation is appropriate?

    Also, please add storborg@mit.edu to the cc list on this ticket. Thanks!

  3. Mike Bayer repo owner
    • changed milestone to 0.6.0

    hey this is a great patch. We just have to work the unittest to use MappedTest, Comparable and eq_ (at the very least speeds up the test to only setup/teardown once for the whole suite) and its good to go.

  4. Log in to comment