diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-08-05 21:47:43 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-08-05 22:13:11 -0400 |
| commit | c7b489b25802f7a25ef78d0731411295c611cc1c (patch) | |
| tree | f5e3b66ab8eb8bb7398c0195fa2b2f1de8ab91c4 /lib/sqlalchemy/orm/attributes.py | |
| parent | 71a3ccbdef0d88e9231b7de9c51e4ed60b3b7181 (diff) | |
| download | sqlalchemy-c7b489b25802f7a25ef78d0731411295c611cc1c.tar.gz | |
Implement relationship AND criteria; global loader criteria
Added the ability to add arbitrary criteria to the ON clause generated
by a relationship attribute in a query, which applies to methods such
as :meth:`_query.Query.join` as well as loader options like
:func:`_orm.joinedload`. Additionally, a "global" version of the option
allows limiting criteria to be applied to particular entities in
a query globally.
Documentation is minimal at this point, new examples will
be coming in a subsequent commit.
Some adjustments to execution options in how they are represented
in the ORMExecuteState as well as well as a few ORM tests that
forgot to get merged in a preceding commit.
Fixes: #4472
Change-Id: I2b8fc57092dedf35ebd16f6343ad0f0d7d332beb
Diffstat (limited to 'lib/sqlalchemy/orm/attributes.py')
| -rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 6dd95a5a9..2e1b9dc75 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -50,6 +50,7 @@ from .. import inspection from .. import util from ..sql import base as sql_base from ..sql import roles +from ..sql import traversals from ..sql import visitors @@ -58,6 +59,7 @@ class QueryableAttribute( interfaces._MappedAttribute, interfaces.InspectionAttr, interfaces.PropComparator, + traversals.HasCopyInternals, roles.JoinTargetRole, roles.OnClauseRole, sql_base.Immutable, @@ -91,6 +93,7 @@ class QueryableAttribute( impl=None, comparator=None, of_type=None, + extra_criteria=(), ): self.class_ = class_ self.key = key @@ -98,6 +101,7 @@ class QueryableAttribute( self.impl = impl self.comparator = comparator self._of_type = of_type + self._extra_criteria = extra_criteria manager = manager_of_class(class_) # manager is None in the case of AliasedClass @@ -114,6 +118,7 @@ class QueryableAttribute( ("key", visitors.ExtendedInternalTraversal.dp_string), ("_parententity", visitors.ExtendedInternalTraversal.dp_multi), ("_of_type", visitors.ExtendedInternalTraversal.dp_multi), + ("_extra_criteria", visitors.InternalTraversal.dp_clauseelement_list), ] def __reduce__(self): @@ -240,6 +245,29 @@ class QueryableAttribute( impl=self.impl, comparator=self.comparator.of_type(entity), of_type=inspection.inspect(entity), + extra_criteria=self._extra_criteria, + ) + + def and_(self, *other): + return QueryableAttribute( + self.class_, + self.key, + self._parententity, + impl=self.impl, + comparator=self.comparator.and_(*other), + of_type=self._of_type, + extra_criteria=self._extra_criteria + other, + ) + + def _clone(self, **kw): + return QueryableAttribute( + self.class_, + self.key, + self._parententity, + impl=self.impl, + comparator=self.comparator, + of_type=self._of_type, + extra_criteria=self._extra_criteria, ) def label(self, name): |
