]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- add some docs to hybrid comparators, operators/comparator logic at the base
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 22 May 2011 19:54:17 +0000 (15:54 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 22 May 2011 19:54:17 +0000 (15:54 -0400)
doc/build/core/expression_api.rst
lib/sqlalchemy/ext/hybrid.py
lib/sqlalchemy/sql/expression.py

index b7004220b92a43e7d1af3c922689980542d11e14..cfa22591dec792ff54900177cacc67a3187a36d4 100644 (file)
@@ -135,6 +135,26 @@ Classes
    :members:
    :undoc-members:
    :inherited-members:
+   :show-inheritance:
+
+   .. automethod:: __eq__
+   .. automethod:: __ne__
+   .. automethod:: __gt__
+   .. automethod:: __ge__
+   .. automethod:: __lt__
+   .. automethod:: __le__
+   .. automethod:: __neg__
+   .. automethod:: __add__
+   .. automethod:: __mul__
+   .. automethod:: __div__
+   .. automethod:: __truediv__
+   .. automethod:: __sub__
+   .. automethod:: __radd__
+   .. automethod:: __rsub__
+   .. automethod:: __rtruediv__
+   .. automethod:: __rdiv__
+   .. automethod:: __rmul__
+   .. automethod:: __mod__
 
 .. autoclass:: CompoundSelect
    :members:
@@ -168,6 +188,14 @@ Classes
    :members:
    :show-inheritance:
 
+.. autoclass:: Operators
+   :members:
+   :undoc-members:
+
+   .. automethod:: __and__
+   .. automethod:: __or__
+   .. automethod:: __invert__
+
 .. autoclass:: Select
    :members:
    :show-inheritance:
index c16c38b2cfa164899ae056cffe3e0a40db89cb95..2c353f11dab3b2b70a241a69b718d80c446abc0f 100644 (file)
@@ -259,7 +259,12 @@ some highly idiosyncratic behavior on the SQL side.
 The example class below allows case-insensitive comparisons on the attribute
 named ``word_insensitive``::
 
-    from sqlalchemy.ext.hybrid import Comparator
+    from sqlalchemy.ext.hybrid import Comparator, hybrid_property
+    from sqlalchemy import func, Column, Integer, String
+    from sqlalchemy.orm import Session
+    from sqlalchemy.ext.declarative import declarative_base
+    
+    Base = declarative_base()
     
     class CaseInsensitiveComparator(Comparator):
         def __eq__(self, other):
@@ -286,6 +291,15 @@ SQL function to both sides::
     FROM searchword 
     WHERE lower(searchword.word) = lower(:lower_1)
 
+The ``CaseInsensitiveComparator`` above implements part of the :class:`.ColumnOperators`
+interface.   A "coercion" operation like lowercasing can be applied to all comparison operations
+(i.e. ``eq``, ``lt``, ``gt``, etc.) using :meth:`.Operators.operate`::
+    
+    class CaseInsensitiveComparator(Comparator):
+        def operate(self, op, other):
+            return op(func.lower(self.__clause_element__()), func.lower(other))
+    
+
 """
 from sqlalchemy import util
 from sqlalchemy.orm import attributes, interfaces
index e06eb61bef607c839f7215949d0d189fc4ed567c..0f06e9ee76e01067c815140e3661f5c19b3c676e 100644 (file)
@@ -1631,6 +1631,15 @@ class _Immutable(object):
         return self
 
 class Operators(object):
+    """Base of comparison and logical operators.
+    
+    Implements base methods :meth:`operate` and :meth:`reverse_operate`,
+    as well as :meth:`__and__`, :meth:`__or__`, :meth:`__invert__`.
+    
+    Usually is used via its most common subclass
+    :class:`.ColumnOperators`.
+    
+    """
     def __and__(self, other):
         return self.operate(operators.and_, other)
 
@@ -1646,13 +1655,65 @@ class Operators(object):
         return op
 
     def operate(self, op, *other, **kwargs):
+        """Operate on an argument.
+        
+        This is the lowest level of operation, raises
+        :class:`NotImplementedError` by default.
+        
+        Overriding this on a subclass can allow common 
+        behavior to be applied to all operations.  
+        For example, overriding :class:`.ColumnOperators`
+        to apply ``func.lower()`` to the left and right 
+        side::
+        
+            class MyComparator(ColumnOperators):
+                def operate(self, op, other):
+                    return op(func.lower(self), func.lower(other))
+
+        :param op:  Operator callable.
+        :param \*other: the 'other' side of the operation. Will
+         be a single scalar for most operations.
+        :param \**kwargs: modifiers.  These may be passed by special
+         operators such as :meth:`ColumnOperators.contains`.
+        
+        
+        """
         raise NotImplementedError(str(op))
 
     def reverse_operate(self, op, other, **kwargs):
+        """Reverse operate on an argument.
+        
+        Usage is the same as :meth:`operate`.
+        
+        """
         raise NotImplementedError(str(op))
 
 class ColumnOperators(Operators):
-    """Defines comparison and math operations."""
+    """Defines comparison and math operations.
+    
+    By default all methods call down to
+    :meth:`Operators.operate` or :meth:`Operators.reverse_operate`
+    passing in the appropriate operator function from the 
+    Python builtin ``operator`` module or
+    a SQLAlchemy-specific operator function from 
+    :mod:`sqlalchemy.expression.operators`.   For example
+    the ``__eq__`` function::
+    
+        def __eq__(self, other):
+            return self.operate(operators.eq, other)
+
+    Where ``operators.eq`` is essentially::
+    
+        def eq(a, b):
+            return a == b
+    
+    A SQLAlchemy construct like :class:`.ColumnElement` ultimately
+    overrides :meth:`.Operators.operate` and others
+    to return further :class:`.ClauseElement` constructs, 
+    so that the ``==`` operation above is replaced by a clause
+    construct.
+    
+    """
 
     timetuple = None
     """Hack, allows datetime objects to be compared on the LHS."""