diff options
Diffstat (limited to 'lib/sqlalchemy/orm')
| -rw-r--r-- | lib/sqlalchemy/orm/__init__.py | 3 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/descriptor_props.py | 27 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 77 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/properties.py | 43 |
4 files changed, 138 insertions, 12 deletions
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index 1a22fe3d1..2078b2396 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -760,6 +760,9 @@ def composite(class_, *cols, **kwargs): See the mapping documentation section :ref:`mapper_composite` for a full usage example. + The :class:`.MapperProperty` returned by :func:`.composite` + is the :class:`.CompositeProperty`. + :param class\_: The "composite type" class. diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 91717974d..f4c2e1a90 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -73,7 +73,17 @@ class DescriptorProperty(MapperProperty): class CompositeProperty(DescriptorProperty): + """Defines a "composite" mapped attribute, representing a collection + of columns as one attribute. + :class:`.CompositeProperty` is constructed using the :func:`.composite` + function. + + See also: + + :ref:`mapper_composite` + + """ def __init__(self, class_, *attrs, **kwargs): self.attrs = attrs self.composite_class = class_ @@ -279,6 +289,23 @@ class CompositeProperty(DescriptorProperty): return self.comparator_factory(self) class Comparator(PropComparator): + """Produce boolean, comparison, and other operators for + :class:`.CompositeProperty` attributes. + + See the example in :ref:`composite_operations` for an overview + of usage , as well as the documentation for :class:`.PropComparator`. + + See also: + + :class:`.PropComparator` + + :class:`.ColumnOperators` + + :ref:`types_operators` + + :attr:`.TypeEngine.comparator_factory` + + """ def __init__(self, prop, adapter=None): self.prop = self.property = prop self.adapter = adapter diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index d0732b913..f41c5894e 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -196,28 +196,91 @@ class MapperProperty(_InspectionAttr): return operator(self.comparator, value) class PropComparator(operators.ColumnOperators): - """Defines comparison operations for MapperProperty objects. + """Defines boolean, comparison, and other operators for + :class:`.MapperProperty` objects. + + SQLAlchemy allows for operators to + be redefined at both the Core and ORM level. :class:`.PropComparator` + is the base class of operator redefinition for ORM-level operations, + including those of :class:`.ColumnProperty`, :class:`.RelationshipProperty`, + and :class:`.CompositeProperty`. + + .. note:: With the advent of Hybrid properties introduced in SQLAlchemy + 0.7, as well as Core-level operator redefinition in + SQLAlchemy 0.8, the use case for user-defined :class:`.PropComparator` + instances is extremely rare. See :ref:`hybrids_toplevel` as well + as :ref:`types_operators`. User-defined subclasses of :class:`.PropComparator` may be created. The built-in Python comparison and math operator methods, such as - ``__eq__()``, ``__lt__()``, ``__add__()``, can be overridden to provide + :meth:`.operators.ColumnOperators.__eq__`, + :meth:`.operators.ColumnOperators.__lt__`, and + :meth:`.operators.ColumnOperators.__add__`, can be overridden to provide new operator behavior. The custom :class:`.PropComparator` is passed to - the mapper property via the ``comparator_factory`` argument. In each case, + the :class:`.MapperProperty` instance via the ``comparator_factory`` + argument. In each case, the appropriate subclass of :class:`.PropComparator` should be used:: + # definition of custom PropComparator subclasses + from sqlalchemy.orm.properties import \\ ColumnProperty,\\ CompositeProperty,\\ RelationshipProperty class MyColumnComparator(ColumnProperty.Comparator): - pass + def __eq__(self, other): + return self.__clause_element__() == other + + class MyRelationshipComparator(RelationshipProperty.Comparator): + def any(self, expression): + "define the 'any' operation" + # ... class MyCompositeComparator(CompositeProperty.Comparator): - pass + def __gt__(self, other): + "redefine the 'greater than' operation" - class MyRelationshipComparator(RelationshipProperty.Comparator): - pass + return sql.and_(*[a>b for a, b in + zip(self.__clause_element__().clauses, + other.__composite_values__())]) + + + # application of custom PropComparator subclasses + + from sqlalchemy.orm import column_property, relationship, composite + from sqlalchemy import Column, String + + class SomeMappedClass(Base): + some_column = column_property(Column("some_column", String), + comparator_factory=MyColumnComparator) + + some_relationship = relationship(SomeOtherClass, + comparator_factory=MyRelationshipComparator) + + some_composite = composite( + Column("a", String), Column("b", String), + comparator_factory=MyCompositeComparator + ) + + Note that for column-level operator redefinition, it's usually + simpler to define the operators at the Core level, using the + :attr:`.TypeEngine.comparator_factory` attribute. See + :ref:`types_operators` for more detail. + + See also: + + :class:`.ColumnProperty.Comparator` + + :class:`.RelationshipProperty.Comparator` + + :class:`.CompositeProperty.Comparator` + + :class:`.ColumnOperators` + + :ref:`types_operators` + + :attr:`.TypeEngine.comparator_factory` """ diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 62e4672d3..f52e914f7 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -161,6 +161,22 @@ class ColumnProperty(StrategizedProperty): dest_state._expire_attributes(dest_dict, [self.key]) class Comparator(PropComparator): + """Produce boolean, comparison, and other operators for + :class:`.ColumnProperty` attributes. + + See the documentation for :class:`.PropComparator` for a brief overview. + + See also: + + :class:`.PropComparator` + + :class:`.ColumnOperators` + + :ref:`types_operators` + + :attr:`.TypeEngine.comparator_factory` + + """ @util.memoized_instancemethod def __clause_element__(self): if self.adapter: @@ -198,9 +214,9 @@ class RelationshipProperty(StrategizedProperty): Public constructor is the :func:`.orm.relationship` function. - Of note here is the :class:`.RelationshipProperty.Comparator` - class, which implements comparison operations for scalar- - and collection-referencing mapped attributes. + See also: + + :ref:`relationship_config_toplevel` """ @@ -304,8 +320,25 @@ class RelationshipProperty(StrategizedProperty): ) class Comparator(PropComparator): - """Produce comparison operations for :func:`~.orm.relationship`-based - attributes.""" + """Produce boolean, comparison, and other operators for + :class:`.RelationshipProperty` attributes. + + See the documentation for :class:`.PropComparator` for a brief overview + of ORM level operator definition. + + See also: + + :class:`.PropComparator` + + :class:`.ColumnProperty.Comparator` + + :class:`.ColumnOperators` + + :ref:`types_operators` + + :attr:`.TypeEngine.comparator_factory` + + """ def __init__(self, prop, mapper, of_type=None, adapter=None): """Construction of :class:`.RelationshipProperty.Comparator` |
