diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-13 16:53:38 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-13 16:53:38 -0400 |
commit | 2937f94e4a05be5b8db268b47745157a143ca30e (patch) | |
tree | cbc5b1eb4dfdc1a1bef9a0eb592ea716f45bec1f /lib/sqlalchemy | |
parent | 37fad88b84db61fba0a09a1c76bcf95d055aa6e2 (diff) | |
download | sqlalchemy-2937f94e4a05be5b8db268b47745157a143ca30e.tar.gz |
- all tests pass
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 3 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/properties.py | 11 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/expression.py | 58 |
3 files changed, 39 insertions, 33 deletions
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index f2014e964..d0732b913 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -237,9 +237,6 @@ class PropComparator(operators.ColumnOperators): return self.__class__(self.prop, self.mapper, adapter) - def __getattr__(self, key): - return getattr(self.__clause_element__(), key) - @staticmethod def any_op(a, b, **kwargs): return a.any(b, **kwargs) diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 53ee1b5fd..62e4672d3 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -168,7 +168,14 @@ class ColumnProperty(StrategizedProperty): else: return self.prop.columns[0]._annotate({ "parententity": self.mapper, - "parentmapper":self.mapper}) + "parentmapper": self.mapper}) + + def __getattr__(self, key): + """proxy attribute access down to the mapped column. + + this allows user-defined comparison methods to be accessed. + """ + return getattr(self.__clause_element__(), key) def operate(self, op, *other, **kwargs): return op(self.__clause_element__(), *other, **kwargs) @@ -254,7 +261,7 @@ class RelationshipProperty(StrategizedProperty): if strategy_class: self.strategy_class = strategy_class - elif self.lazy== 'dynamic': + elif self.lazy == 'dynamic': from sqlalchemy.orm import dynamic self.strategy_class = dynamic.DynaLoader else: diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index b92ec4529..6021b40b1 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -1988,55 +1988,58 @@ class _DefaultColumnComparator(ColumnOperators): return self.__compare(expr, op, ClauseList(*args).self_group(against=op), negate=negate_op) - def _neg_impl(self): + def _neg_impl(self, expr, op, **kw): """See :meth:`.ColumnOperators.__neg__`.""" - return UnaryExpression(self.expr, operator=operators.neg) + return UnaryExpression(expr, operator=operators.neg) - def _startswith_impl(self, other, escape=None): + def _startswith_impl(self, expr, op, other, escape=None): """See :meth:`.ColumnOperators.startswith`.""" # use __radd__ to force string concat behavior return self.__compare( + expr, operators.like_op, literal_column("'%'", type_=sqltypes.String).__radd__( - self._check_literal(operators.like_op, other) + self._check_literal(expr, operators.like_op, other) ), escape=escape) - def _endswith_impl(self, other, escape=None): + def _endswith_impl(self, expr, op, other, escape=None): """See :meth:`.ColumnOperators.endswith`.""" return self.__compare( + expr, operators.like_op, literal_column("'%'", type_=sqltypes.String) + - self._check_literal(operators.like_op, other), + self._check_literal(expr, operators.like_op, other), escape=escape) - def _contains_impl(self, other, escape=None): + def _contains_impl(self, expr, op, other, escape=None): """See :meth:`.ColumnOperators.contains`.""" return self.__compare( + expr, operators.like_op, literal_column("'%'", type_=sqltypes.String) + - self._check_literal(operators.like_op, other) + + self._check_literal(expr, operators.like_op, other) + literal_column("'%'", type_=sqltypes.String), escape=escape) - def _match_impl(self, other): + def _match_impl(self, expr, op, other): """See :meth:`.ColumnOperators.match`.""" - return self.__compare(operators.match_op, - self._check_literal(operators.match_op, + return self.__compare(expr, operators.match_op, + self._check_literal(expr, operators.match_op, other)) - def _distinct_impl(self): + def _distinct_impl(self, expr, op): """See :meth:`.ColumnOperators.distinct`.""" - return UnaryExpression(self, operator=operators.distinct_op, - type_=self.type) + return UnaryExpression(expr, operator=operators.distinct_op, + type_=expr.type) - def _between_impl(self, cleft, cright): + def _between_impl(self, expr, op, cleft, cright, **kw): """See :meth:`.ColumnOperators.between`.""" return BinaryExpression( - self, + expr, ClauseList( - self._check_literal(operators.and_, cleft), - self._check_literal(operators.and_, cright), + self._check_literal(expr, operators.and_, cleft), + self._check_literal(expr, operators.and_, cright), operator=operators.and_, group=False), operators.between_op) @@ -2068,6 +2071,13 @@ class _DefaultColumnComparator(ColumnOperators): "nullslast_op": (__scalar, nullslast), "in_op": (_in_impl, operators.notin_op), "collate": (_collate_impl,), + "match_op": (_match_impl,), + "distinct_op": (_distinct_impl,), + "between_op": (_between_impl, ), + "contains_op": (_contains_impl, ), + "startswith_op": (_startswith_impl,), + "endswith_op": (_endswith_impl,), + "neg": (_neg_impl,), } def operate(self, expr, op, *other, **kwargs): @@ -2194,7 +2204,7 @@ class ColumnElement(ClauseElement, ColumnOperators): if self.comparator: return op(other, self.comparator, **kwargs) else: - return _DEFAULT_COMPARATOR.reverse_operate(self, op, *other, **kwargs) + return _DEFAULT_COMPARATOR.reverse_operate(self, op, other, **kwargs) def _bind_param(self, operator, obj): return BindParameter(None, obj, @@ -3130,13 +3140,6 @@ class ClauseList(ClauseElement): _literal_as_text(clause) for clause in clauses if clause is not None] - @util.memoized_property - def type(self): - if self.clauses: - return self.clauses[0].type - else: - return sqltypes.NULLTYPE - def __iter__(self): return iter(self.clauses) @@ -4288,8 +4291,7 @@ class ColumnClause(Immutable, ColumnElement): _as_truncated(name if name else self.name), selectable=selectable, type_=self.type, - is_literal=is_literal, - comparator_factory=self.comparator_factory + is_literal=is_literal ) c.proxies = [self] if selectable._is_clone_of is not None: |