From: Mike Bayer Date: Wed, 25 Apr 2012 02:11:15 +0000 (-0400) Subject: document the remote/foreign/remote_foreign functions X-Git-Tag: rel_0_8_0b1~443 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=65862c5e2eeb49939e172846fb9f940ba05ce6d5;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git document the remote/foreign/remote_foreign functions --- diff --git a/doc/build/orm/relationships.rst b/doc/build/orm/relationships.rst index c2ab62487f..a68dad11ee 100644 --- a/doc/build/orm/relationships.rst +++ b/doc/build/orm/relationships.rst @@ -1255,4 +1255,11 @@ Relationships API .. autofunction:: dynamic_loader +.. autofunction:: foreign + +.. autofunction:: remote + +.. autofunction:: remote_foreign + + diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index d322d426b7..1c3554a5b9 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -396,6 +396,11 @@ def relationship(argument, secondary=None, **kwargs): which is evaluated at mapper initialization time, and may be passed as a Python-evaluable string when using Declarative. + As of 0.8, the :func:`.foreign` annotation can also be applied + directly to the ``primaryjoin`` expression, which is an alternate, + more specific system of describing which columns in a particular + ``primaryjoin`` should be considered "foreign". + :param innerjoin=False: when ``True``, joined eager loads will use an inner join to join against related tables instead of an outer join. The purpose @@ -582,6 +587,11 @@ def relationship(argument, secondary=None, **kwargs): which is evaluated at mapper initialization time, and may be passed as a Python-evaluable string when using Declarative. + As of 0.8, the :func:`.remote` annotation can also be applied + directly to the ``primaryjoin`` expression, which is an alternate, + more specific system of describing which columns in a particular + ``primaryjoin`` should be considered "remote". + :param query_class: a :class:`.Query` subclass that will be used as the base of the "appender query" returned by a "dynamic" relationship, that diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py index c9cd61c8c6..9b828ee047 100644 --- a/lib/sqlalchemy/orm/relationships.py +++ b/lib/sqlalchemy/orm/relationships.py @@ -21,12 +21,75 @@ from sqlalchemy.sql import operators, expression, visitors from sqlalchemy.orm.interfaces import MANYTOMANY, MANYTOONE, ONETOMANY def remote(expr): + """Annotate a portion of a primaryjoin expression + with a 'remote' annotation. + + :func:`.remote`, :func:`.foreign`, and :func:`.remote_foreign` + are intended to be used with + :func:`.relationship` in conjunction with a + ``primaryjoin`` expression which contains + indirect equality conditions, meaning the comparison + of mapped columns involves extraneous SQL functions + such as :func:`.cast`. They can also be used in + lieu of the ``foreign_keys`` and ``remote_side`` + parameters to :func:`.relationship`, if a + primaryjoin expression is also being sent explicitly. + + Below, a mapped class ``DNSRecord`` relates to the + ``DHCPHost`` class using a primaryjoin that casts + the ``content`` column to a string. The :func:`.foreign` + and :func:`.remote` annotation functions are used + to mark with full accuracy those mapped columns that + are significant to the :func:`.relationship`, in terms + of how they are joined:: + + from sqlalchemy import cast, String + from sqlalchemy.orm import remote, foreign + from sqlalchemy.dialects.postgresql import INET + + class DNSRecord(Base): + __tablename__ = 'dns' + + id = Column(Integer, primary_key=True) + content = Column(INET) + dhcphost = relationship(DHCPHost, + primaryjoin=cast(foreign(content), String) == + remote(DHCPHost.ip_address) + ) + + New in 0.8. + + See also: + + * :func:`.foreign` + + * :func:`.remote_foreign` + + """ return _annotate_columns(expr, {"remote":True}) def foreign(expr): + """Annotate a portion of a primaryjoin expression + with a 'foreign' annotation. + + See the example at :func:`.remote`. + + New in 0.8. + + """ + return _annotate_columns(expr, {"foreign":True}) def remote_foreign(expr): + """Annotate a portion of a primaryjoin expression + with a 'remote' and 'foreign' annotation. + + See the example at :func:`.remote`. + + New in 0.8. + + """ + return _annotate_columns(expr, {"foreign":True, "remote":True})