From: Mike Bayer Date: Thu, 25 Apr 2019 15:46:31 +0000 (-0500) Subject: Add ORM documentation for as_comparison() X-Git-Tag: rel_1_3_4~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b954be661bdea254d86481e9bd31f2a84fadaa7a;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Add ORM documentation for as_comparison() In #3831 we added the ability for SQL functions to be used in primaryjoin conditions as the source of comparison, however we didn't add documentation from the main relationship docs so nobody could find it unless they read the migration notes. Since the two use cases that have come up for this are materialized path with string functions, and geometry functions, add the example based on the use case requested in https://github.com/geoalchemy/geoalchemy2/issues/220#issuecomment-486709055 This example hasn't been tested yet and is subject to revision. Change-Id: I410d8ffade3f17cf616fc5056f27d7d32092207b --- diff --git a/doc/build/orm/join_conditions.rst b/doc/build/orm/join_conditions.rst index e9c51c14d8..8a29fdc5d7 100644 --- a/doc/build/orm/join_conditions.rst +++ b/doc/build/orm/join_conditions.rst @@ -294,6 +294,45 @@ Will render as:: flag to assist in the creation of :func:`.relationship` constructs using custom operators. +Custom operators based on SQL functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A variant to the use case for :paramref:`~.Operators.op.is_comparison` is +when we aren't using an operator, but a SQL function. The typical example +of this use case is the PostgreSQL PostGIS functions however any SQL +function on any database that resolves to a binary condition may apply. +To suit this use case, the :meth:`.FunctionElement.as_comparison` method +can modify any SQL function, such as those invoked from the :data:`.func` +namespace, to indicate to the ORM that the function produces a comparison of +two expressions. The below example illustrates this with the +`Geoalchemy2 ` library:: + + from geoalchemy2 import Geometry + from sqlalchemy import Column, Integer, func + from sqlalchemy.orm import relationship, foreign + + class Polygon(Base): + __tablename__ = "polygon" + id = Column(Integer, primary_key=True) + geom = Column(Geometry("POLYGON", srid=4326)) + points = relationship( + "Point", + primaryjoin="func.ST_Contains(foreign(Polygon.geom), Point.geom).as_comparison(1, 2)", + viewonly=True, + ) + + class Point(Base): + __tablename__ = "point" + id = Column(Integer, primary_key=True) + geom = Column(Geometry("POINT", srid=4326)) + +Above, the :meth:`.FunctionElement.as_comparison` indicates that the +``func.ST_Contains()`` SQL function is comparing the ``Polygon.geom`` and +``Point.geom`` expressions. The :func:`.foreign` annotation additionally notes +which column takes on the "foreign key" role in this particular relationship. + +.. versionadded:: 1.3 Added :meth:`.FunctionElement.as_comparison`. + .. _relationship_overlapping_foreignkeys: Overlapping Foreign Keys