diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2019-01-15 15:06:05 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@bbpush.zzzcomputing.com> | 2019-01-15 15:06:05 +0000 |
| commit | c1a53669c832c9e0ef813b207307500cb20c58da (patch) | |
| tree | 49b98d05ec6da816946393834681cb2d09123909 /lib/sqlalchemy | |
| parent | e288092848e38eda829097a03e750462c14bad15 (diff) | |
| parent | 836178d42620869c3cab4b7f41d24560f0098c87 (diff) | |
| download | sqlalchemy-c1a53669c832c9e0ef813b207307500cb20c58da.tar.gz | |
Merge "Relax "ambiguous" association proxy restrictions, support Proxy"
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/ext/associationproxy.py | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index 59ed1aa99..5b05d2b3d 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -380,7 +380,12 @@ class AssociationProxyInstance(object): parent, owning_class, target_class, value_attr ) - is_object = getattr(target_class, value_attr).impl.uses_objects + attr = getattr(target_class, value_attr) + if attr._is_internal_proxy and not hasattr(attr, "impl"): + return AmbiguousAssociationProxyInstance( + parent, owning_class, target_class, value_attr + ) + is_object = attr.impl.uses_objects if is_object: return ObjectAssociationProxyInstance( parent, owning_class, target_class, value_attr @@ -739,13 +744,10 @@ class AmbiguousAssociationProxyInstance(AssociationProxyInstance): ) def get(self, obj): - self._ambiguous() - - def set(self, obj, values): - self._ambiguous() - - def delete(self, obj): - self._ambiguous() + if obj is None: + self._ambiguous() + else: + return super(AmbiguousAssociationProxyInstance, self).get(obj) def any(self, criterion=None, **kwargs): self._ambiguous() @@ -764,25 +766,31 @@ class AmbiguousAssociationProxyInstance(AssociationProxyInstance): if parent_instance is not None: actual_obj = getattr(parent_instance, self.target_collection) if actual_obj is not None: - instance_class = type(actual_obj) - if instance_class not in self._lookup_cache: - self._populate_cache(instance_class) - try: - return self._lookup_cache[instance_class] - except KeyError: + insp = inspect(actual_obj) + except exc.NoInspectionAvailable: pass + else: + mapper = insp.mapper + instance_class = mapper.class_ + if instance_class not in self._lookup_cache: + self._populate_cache(instance_class, mapper) + + try: + return self._lookup_cache[instance_class] + except KeyError: + pass # no object or ambiguous object given, so return "self", which - # is a no-op proxy. + # is a proxy with generally only instance-level functionality return self - def _populate_cache(self, instance_class): + def _populate_cache(self, instance_class, mapper): prop = orm.class_mapper(self.owning_class).get_property( self.target_collection ) - if inspect(instance_class).mapper.isa(prop.mapper): + if mapper.isa(prop.mapper): target_class = instance_class try: target_assoc = self._cls_unwrap_target_assoc_proxy( |
