Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

aroundthecode / SQLAlchemy   python

Repository URL to install this package:

Version: 1.2.10 

/ orm / relationships.py

# orm/relationships.py
# Copyright (C) 2005-2018 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

"""Heuristics related to join conditions as used in
:func:`.relationship`.

Provides the :class:`.JoinCondition` object, which encapsulates
SQL annotation and aliasing behavior focused on the `primaryjoin`
and `secondaryjoin` aspects of :func:`.relationship`.

"""
from __future__ import absolute_import
from .. import sql, util, exc as sa_exc, schema, log

import weakref
from .util import CascadeOptions, _orm_annotate, _orm_deannotate
from . import dependency
from . import attributes
from ..sql.util import (
    ClauseAdapter,
    join_condition, _shallow_annotate, visit_binary_product,
    _deep_deannotate, selectables_overlap, adapt_criterion_to_null
)
from ..sql import operators, expression, visitors
from .interfaces import (MANYTOMANY, MANYTOONE, ONETOMANY,
                         StrategizedProperty, PropComparator)
from ..inspection import inspect
from . import mapper as mapperlib
import collections


def remote(expr):
    """Annotate a portion of a primaryjoin expression
    with a 'remote' annotation.

    See the section :ref:`relationship_custom_foreign` for a
    description of use.

    .. versionadded:: 0.8

    .. seealso::

        :ref:`relationship_custom_foreign`

        :func:`.foreign`

    """
    return _annotate_columns(expression._clause_element_as_expr(expr),
                             {"remote": True})


def foreign(expr):
    """Annotate a portion of a primaryjoin expression
    with a 'foreign' annotation.

    See the section :ref:`relationship_custom_foreign` for a
    description of use.

    .. versionadded:: 0.8

    .. seealso::

        :ref:`relationship_custom_foreign`

        :func:`.remote`

    """

    return _annotate_columns(expression._clause_element_as_expr(expr),
                             {"foreign": True})


@log.class_logger
@util.langhelpers.dependency_for("sqlalchemy.orm.properties")
class RelationshipProperty(StrategizedProperty):
    """Describes an object property that holds a single item or list
    of items that correspond to a related database table.

    Public constructor is the :func:`.orm.relationship` function.

    See also:

    :ref:`relationship_config_toplevel`

    """

    strategy_wildcard_key = 'relationship'

    _dependency_processor = None

    def __init__(self, argument,
                 secondary=None, primaryjoin=None,
                 secondaryjoin=None,
                 foreign_keys=None,
                 uselist=None,
                 order_by=False,
                 backref=None,
                 back_populates=None,
                 post_update=False,
                 cascade=False, extension=None,
                 viewonly=False, lazy="select",
                 collection_class=None, passive_deletes=False,
                 passive_updates=True, remote_side=None,
                 enable_typechecks=True, join_depth=None,
                 comparator_factory=None,
                 single_parent=False, innerjoin=False,
                 distinct_target_key=None,
                 doc=None,
                 active_history=False,
                 cascade_backrefs=True,
                 load_on_pending=False,
                 bake_queries=True,
                 _local_remote_pairs=None,
                 query_class=None,
                 info=None):
        """Provide a relationship between two mapped classes.

        This corresponds to a parent-child or associative table relationship.
        The constructed class is an instance of
        :class:`.RelationshipProperty`.

        A typical :func:`.relationship`, used in a classical mapping::

           mapper(Parent, properties={
             'children': relationship(Child)
           })

        Some arguments accepted by :func:`.relationship` optionally accept a
        callable function, which when called produces the desired value.
        The callable is invoked by the parent :class:`.Mapper` at "mapper
        initialization" time, which happens only when mappers are first used,
        and is assumed to be after all mappings have been constructed.  This
        can be used to resolve order-of-declaration and other dependency
        issues, such as if ``Child`` is declared below ``Parent`` in the same
        file::

            mapper(Parent, properties={
                "children":relationship(lambda: Child,
                                    order_by=lambda: Child.id)
            })

        When using the :ref:`declarative_toplevel` extension, the Declarative
        initializer allows string arguments to be passed to
        :func:`.relationship`.  These string arguments are converted into
        callables that evaluate the string as Python code, using the
        Declarative class-registry as a namespace.  This allows the lookup of
        related classes to be automatic via their string name, and removes the
        need to import related classes at all into the local module space::

            from sqlalchemy.ext.declarative import declarative_base

            Base = declarative_base()

            class Parent(Base):
                __tablename__ = 'parent'
                id = Column(Integer, primary_key=True)
                children = relationship("Child", order_by="Child.id")

        .. seealso::

          :ref:`relationship_config_toplevel` - Full introductory and
          reference documentation for :func:`.relationship`.

          :ref:`orm_tutorial_relationship` - ORM tutorial introduction.

        :param argument:
          a mapped class, or actual :class:`.Mapper` instance, representing
          the target of the relationship.

          :paramref:`~.relationship.argument` may also be passed as a callable
          function which is evaluated at mapper initialization time, and may
          be passed as a Python-evaluable string when using Declarative.

          .. seealso::

            :ref:`declarative_configuring_relationships` - further detail
            on relationship configuration when using Declarative.

        :param secondary:
          for a many-to-many relationship, specifies the intermediary
          table, and is typically an instance of :class:`.Table`.
          In less common circumstances, the argument may also be specified
          as an :class:`.Alias` construct, or even a :class:`.Join` construct.

          :paramref:`~.relationship.secondary` may
          also be passed as a callable function which is evaluated at
          mapper initialization time.  When using Declarative, it may also
          be a string argument noting the name of a :class:`.Table` that is
          present in the :class:`.MetaData` collection associated with the
          parent-mapped :class:`.Table`.

          The :paramref:`~.relationship.secondary` keyword argument is
          typically applied in the case where the intermediary :class:`.Table`
          is not otherwise expressed in any direct class mapping. If the
          "secondary" table is also explicitly mapped elsewhere (e.g. as in
          :ref:`association_pattern`), one should consider applying the
          :paramref:`~.relationship.viewonly` flag so that this
          :func:`.relationship` is not used for persistence operations which
          may conflict with those of the association object pattern.

          .. seealso::

              :ref:`relationships_many_to_many` - Reference example of "many
              to many".

              :ref:`orm_tutorial_many_to_many` - ORM tutorial introduction to
              many-to-many relationships.

              :ref:`self_referential_many_to_many` - Specifics on using
              many-to-many in a self-referential case.

              :ref:`declarative_many_to_many` - Additional options when using
              Declarative.

              :ref:`association_pattern` - an alternative to
              :paramref:`~.relationship.secondary` when composing association
              table relationships, allowing additional attributes to be
              specified on the association table.

              :ref:`composite_secondary_join` - a lesser-used pattern which
              in some cases can enable complex :func:`.relationship` SQL
              conditions to be used.

          .. versionadded:: 0.9.2 :paramref:`~.relationship.secondary` works
             more effectively when referring to a :class:`.Join` instance.

        :param active_history=False:
          When ``True``, indicates that the "previous" value for a
          many-to-one reference should be loaded when replaced, if
          not already loaded. Normally, history tracking logic for
          simple many-to-ones only needs to be aware of the "new"
          value in order to perform a flush. This flag is available
          for applications that make use of
          :func:`.attributes.get_history` which also need to know
          the "previous" value of the attribute.

        :param backref:
          indicates the string name of a property to be placed on the related
          mapper's class that will handle this relationship in the other
          direction. The other property will be created automatically
          when the mappers are configured.  Can also be passed as a
          :func:`.backref` object to control the configuration of the
          new relationship.

          .. seealso::

            :ref:`relationships_backref` - Introductory documentation and
            examples.

            :paramref:`~.relationship.back_populates` - alternative form
            of backref specification.

            :func:`.backref` - allows control over :func:`.relationship`
            configuration when using :paramref:`~.relationship.backref`.


        :param back_populates:
          Takes a string name and has the same meaning as
          :paramref:`~.relationship.backref`, except the complementing
          property is **not** created automatically, and instead must be
          configured explicitly on the other mapper.  The complementing
          property should also indicate
          :paramref:`~.relationship.back_populates` to this relationship to
          ensure proper functioning.

          .. seealso::

            :ref:`relationships_backref` - Introductory documentation and
            examples.

            :paramref:`~.relationship.backref` - alternative form
            of backref specification.

        :param bake_queries=True:
          Use the :class:`.BakedQuery` cache to cache the construction of SQL
          used in lazy loads.  True by default.   Set to False if the
          join condition of the relationship has unusual features that
          might not respond well to statement caching.

          .. versionchanged:: 1.2
             "Baked" loading is the default implementation for the "select",
             a.k.a. "lazy" loading strategy for relationships.

          .. versionadded:: 1.0.0

          .. seealso::

            :ref:`baked_toplevel`

        :param cascade:
          a comma-separated list of cascade rules which determines how
          Session operations should be "cascaded" from parent to child.
          This defaults to ``False``, which means the default cascade
          should be used - this default cascade is ``"save-update, merge"``.

          The available cascades are ``save-update``, ``merge``,
          ``expunge``, ``delete``, ``delete-orphan``, and ``refresh-expire``.
          An additional option, ``all`` indicates shorthand for
          ``"save-update, merge, refresh-expire,
          expunge, delete"``, and is often used as in ``"all, delete-orphan"``
          to indicate that related objects should follow along with the
          parent object in all cases, and be deleted when de-associated.

          .. seealso::

            :ref:`unitofwork_cascades` - Full detail on each of the available
            cascade options.

            :ref:`tutorial_delete_cascade` - Tutorial example describing
            a delete cascade.

        :param cascade_backrefs=True:
          a boolean value indicating if the ``save-update`` cascade should
          operate along an assignment event intercepted by a backref.
          When set to ``False``, the attribute managed by this relationship
          will not cascade an incoming transient object into the session of a
          persistent parent, if the event is received via backref.

          .. seealso::

            :ref:`backref_cascade` - Full discussion and examples on how
            the :paramref:`~.relationship.cascade_backrefs` option is used.

        :param collection_class:
          a class or callable that returns a new list-holding object. will
          be used in place of a plain list for storing elements.

          .. seealso::

            :ref:`custom_collections` - Introductory documentation and
            examples.

        :param comparator_factory:
          a class which extends :class:`.RelationshipProperty.Comparator`
          which provides custom SQL clause generation for comparison
          operations.

          .. seealso::

            :class:`.PropComparator` - some detail on redefining comparators
            at this level.
Loading ...