summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2021-04-16 08:56:17 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2021-04-16 11:29:53 -0400
commitb73fc8f874da94c9c5b2d94feb6b1b45b7f4f02b (patch)
treea008891963604495c33205f3fcc0f92aba623592 /lib/sqlalchemy
parentb3d764fa768756cd7aef73253ccceac456c76c81 (diff)
downloadsqlalchemy-b73fc8f874da94c9c5b2d94feb6b1b45b7f4f02b.tar.gz
synonym fixes and enhancements
Fixed regression where an attribute that is mapped to a :func:`_orm.synonym` could not be used in column loader options such as :func:`_orm.load_only`. Established support for :func:`_orm.synonym` in conjunction with hybrid property, associationproxy, including that synonyms can be established linking to these constructs which work fully. This is a behavior that was semi-explicitly disallowed previously, however since it did not fail in every scenario, explicit support for assoc proxy and hybrids has been added. Fixes: #6272 Fixes: #6267 Change-Id: Ie75bb3b535feeb6ccf3f6a391f21b69f241e625e
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/attributes.py2
-rw-r--r--lib/sqlalchemy/orm/descriptor_props.py25
2 files changed, 20 insertions, 7 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py
index d1ed17f1a..9e326db64 100644
--- a/lib/sqlalchemy/orm/attributes.py
+++ b/lib/sqlalchemy/orm/attributes.py
@@ -487,6 +487,8 @@ def create_proxied_attribute(descriptor):
"""
+ _extra_criteria = ()
+
def __init__(
self,
class_,
diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py
index c30672566..f8c42ee60 100644
--- a/lib/sqlalchemy/orm/descriptor_props.py
+++ b/lib/sqlalchemy/orm/descriptor_props.py
@@ -22,6 +22,7 @@ from .. import schema
from .. import sql
from .. import util
from ..sql import expression
+from ..sql import operators
class DescriptorProperty(MapperProperty):
@@ -665,15 +666,22 @@ class SynonymProperty(DescriptorProperty):
def uses_objects(self):
return getattr(self.parent.class_, self.name).impl.uses_objects
- # TODO: when initialized, check _proxied_property,
+ # TODO: when initialized, check _proxied_object,
# emit a warning if its not a column-based property
@util.memoized_property
- def _proxied_property(self):
+ def _proxied_object(self):
attr = getattr(self.parent.class_, self.name)
if not hasattr(attr, "property") or not isinstance(
attr.property, MapperProperty
):
+ # attribute is a non-MapperProprerty proxy such as
+ # hybrid or association proxy
+ if isinstance(attr, attributes.QueryableAttribute):
+ return attr.comparator
+ elif isinstance(attr, operators.ColumnOperators):
+ return attr
+
raise sa_exc.InvalidRequestError(
"""synonym() attribute "%s.%s" only supports """
"""ORM mapped attributes, got %r"""
@@ -682,13 +690,16 @@ class SynonymProperty(DescriptorProperty):
return attr.property
def _comparator_factory(self, mapper):
- prop = self._proxied_property
+ prop = self._proxied_object
- if self.comparator_factory:
- comp = self.comparator_factory(prop, mapper)
+ if isinstance(prop, MapperProperty):
+ if self.comparator_factory:
+ comp = self.comparator_factory(prop, mapper)
+ else:
+ comp = prop.comparator_factory(prop, mapper)
+ return comp
else:
- comp = prop.comparator_factory(prop, mapper)
- return comp
+ return prop
def get_history(self, *arg, **kw):
attr = getattr(self.parent.class_, self.name)