summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-08-13 16:53:38 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-08-13 16:53:38 -0400
commit2937f94e4a05be5b8db268b47745157a143ca30e (patch)
treecbc5b1eb4dfdc1a1bef9a0eb592ea716f45bec1f
parent37fad88b84db61fba0a09a1c76bcf95d055aa6e2 (diff)
downloadsqlalchemy-2937f94e4a05be5b8db268b47745157a143ca30e.tar.gz
- all tests pass
-rw-r--r--lib/sqlalchemy/orm/interfaces.py3
-rw-r--r--lib/sqlalchemy/orm/properties.py11
-rw-r--r--lib/sqlalchemy/sql/expression.py58
-rw-r--r--test/lib/profiles.txt19
-rw-r--r--test/orm/test_mapper.py6
-rw-r--r--test/sql/test_compiler.py2
-rw-r--r--test/sql/test_query.py8
7 files changed, 53 insertions, 54 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:
diff --git a/test/lib/profiles.txt b/test/lib/profiles.txt
index db427d701..5572a8ebc 100644
--- a/test/lib/profiles.txt
+++ b/test/lib/profiles.txt
@@ -1,4 +1,4 @@
-# /Users/classic/dev/sqlalchemy/./test/lib/profiles.txt
+# /Users/classic/dev/sqla_comparators/./test/lib/profiles.txt
# This file is written out on a per-environment basis.
# For each test in aaa_profiling, the corresponding function and
# environment is located within this file. If it doesn't exist,
@@ -195,16 +195,13 @@ test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute 3.2_
# TEST: test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.5_sqlite_pysqlite_nocextensions 9
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.6_sqlite_pysqlite_nocextensions 9
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_mysql_mysqldb_cextensions 9
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_mysql_mysqldb_nocextensions 9
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_postgresql_psycopg2_cextensions 9
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_postgresql_psycopg2_nocextensions 9
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_sqlite_pysqlite_cextensions 9
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_sqlite_pysqlite_nocextensions 9
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 3.2_postgresql_psycopg2_nocextensions 10
-test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 3.2_sqlite_pysqlite_nocextensions 10
+test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.6_sqlite_pysqlite_nocextensions 12
+test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_mysql_mysqldb_cextensions 12
+test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_mysql_mysqldb_nocextensions 12
+test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_postgresql_psycopg2_cextensions 12
+test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_postgresql_psycopg2_nocextensions 12
+test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_sqlite_pysqlite_cextensions 12
+test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_sqlite_pysqlite_nocextensions 12
# TEST: test.aaa_profiling.test_resultset.ResultSetTest.test_string
diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py
index 9e6e7fbbf..a87c064cf 100644
--- a/test/orm/test_mapper.py
+++ b/test/orm/test_mapper.py
@@ -1269,7 +1269,8 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
def __getitem__(self, key):
return 'value'
- class UCComparator(sa.orm.PropComparator):
+ from sqlalchemy.orm.properties import ColumnProperty
+ class UCComparator(ColumnProperty.Comparator):
__hash__ = None
def method1(self):
@@ -1314,7 +1315,8 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
assert_raises_message(
AttributeError,
- "Neither 'extendedproperty' object nor 'UCComparator' object has an attribute 'nonexistent'",
+ "Neither 'extendedproperty' object nor 'UCComparator' "
+ "object has an attribute 'nonexistent'",
getattr, User.uc_name, 'nonexistent')
# test compile
diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py
index aee170d15..64d50a1d5 100644
--- a/test/sql/test_compiler.py
+++ b/test/sql/test_compiler.py
@@ -940,6 +940,8 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
table1.c.myid.like('hoho')
eq_(str(clause), str(util.pickle.loads(util.pickle.dumps(clause))))
+ clause = tuple_(1, 2, 3)
+ eq_(str(clause), str(util.pickle.loads(util.pickle.dumps(clause))))
def test_like(self):
for expr, check, dialect in [
diff --git a/test/sql/test_query.py b/test/sql/test_query.py
index 2541d0711..1ae15707a 100644
--- a/test/sql/test_query.py
+++ b/test/sql/test_query.py
@@ -1012,14 +1012,6 @@ class QueryTest(fixtures.TestBase):
r = testing.db.execute('select user_name from query_users').first()
eq_(len(r), 1)
- @testing.uses_deprecated(r'.*which subclass Executable')
- def test_cant_execute_join(self):
- try:
- users.join(addresses).execute()
- except exc.StatementError, e:
- assert str(e).startswith('Not an executable clause ')
-
-
def test_column_order_with_simple_query(self):
# should return values in column definition order