Interpret this expression as a boolean comparison between two values. This method is used for an ORM use case described at :ref:`relationship_custom_operator_sql_function`. A hypothetical SQL function "is_equal()" which compares to values for equality would
(
self, left_index: int, right_index: int
)
| 593 | return FunctionFilter(self, *criterion) |
| 594 | |
| 595 | def as_comparison( |
| 596 | self, left_index: int, right_index: int |
| 597 | ) -> FunctionAsBinary: |
| 598 | """Interpret this expression as a boolean comparison between two |
| 599 | values. |
| 600 | |
| 601 | This method is used for an ORM use case described at |
| 602 | :ref:`relationship_custom_operator_sql_function`. |
| 603 | |
| 604 | A hypothetical SQL function "is_equal()" which compares to values |
| 605 | for equality would be written in the Core expression language as:: |
| 606 | |
| 607 | expr = func.is_equal("a", "b") |
| 608 | |
| 609 | If "is_equal()" above is comparing "a" and "b" for equality, the |
| 610 | :meth:`.FunctionElement.as_comparison` method would be invoked as:: |
| 611 | |
| 612 | expr = func.is_equal("a", "b").as_comparison(1, 2) |
| 613 | |
| 614 | Where above, the integer value "1" refers to the first argument of the |
| 615 | "is_equal()" function and the integer value "2" refers to the second. |
| 616 | |
| 617 | This would create a :class:`.BinaryExpression` that is equivalent to:: |
| 618 | |
| 619 | BinaryExpression("a", "b", operator=op.eq) |
| 620 | |
| 621 | However, at the SQL level it would still render as |
| 622 | "is_equal('a', 'b')". |
| 623 | |
| 624 | The ORM, when it loads a related object or collection, needs to be able |
| 625 | to manipulate the "left" and "right" sides of the ON clause of a JOIN |
| 626 | expression. The purpose of this method is to provide a SQL function |
| 627 | construct that can also supply this information to the ORM, when used |
| 628 | with the :paramref:`_orm.relationship.primaryjoin` parameter. The |
| 629 | return value is a containment object called :class:`.FunctionAsBinary`. |
| 630 | |
| 631 | An ORM example is as follows:: |
| 632 | |
| 633 | class Venue(Base): |
| 634 | __tablename__ = "venue" |
| 635 | id = Column(Integer, primary_key=True) |
| 636 | name = Column(String) |
| 637 | |
| 638 | descendants = relationship( |
| 639 | "Venue", |
| 640 | primaryjoin=func.instr( |
| 641 | remote(foreign(name)), name + "/" |
| 642 | ).as_comparison(1, 2) |
| 643 | == 1, |
| 644 | viewonly=True, |
| 645 | order_by=name, |
| 646 | ) |
| 647 | |
| 648 | Above, the "Venue" class can load descendant "Venue" objects by |
| 649 | determining if the name of the parent Venue is contained within the |
| 650 | start of the hypothetical descendant value's name, e.g. "parent1" would |
| 651 | match up to "parent1/child1", but not to "parent2/child1". |
| 652 |