diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-12-14 13:49:11 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-12-14 15:38:32 -0500 |
commit | 2bac535f506dd68595d64d6cdf21e2d4937c2c9f (patch) | |
tree | 7e05f77fa8fccbd63c2d1488278af6e5f56c325d /lib/sqlalchemy/orm/mapper.py | |
parent | a8d76cff39dbaf6354d42d35cd68332df469d124 (diff) | |
download | sqlalchemy-2bac535f506dd68595d64d6cdf21e2d4937c2c9f.tar.gz |
warn when backref will replace existing userland descriptor
A warning is emitted if a backref name used in :func:`_orm.relationship`
names an attribute on the target class which already has a method or
attribute assigned to that name, as the backref declaration will replace
that attribute.
Fixes: #4629
Change-Id: I0059b35ce60f43b0f3d8be008f12411154484ea1
Diffstat (limited to 'lib/sqlalchemy/orm/mapper.py')
-rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 7a7524621..93b6c4ecb 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -1658,7 +1658,7 @@ class Mapper( ) continue - self._configure_property(key, possible_col_prop, False) + self._configure_property(key, possible_col_prop, init=False) # step 2: pull properties from the inherited mapper. reconcile # columns with those which are explicit above. for properties that @@ -1698,7 +1698,7 @@ class Mapper( # it now in the order in which it corresponds to the # Table / selectable key, prop = explicit_col_props_by_column[column] - self._configure_property(key, prop, False) + self._configure_property(key, prop, init=False) continue elif column in self._columntoproperty: @@ -1962,8 +1962,10 @@ class Mapper( self, key: str, prop_arg: Union[KeyedColumnElement[Any], MapperProperty[Any]], + *, init: bool = True, setparent: bool = True, + warn_for_existing: bool = False, ) -> MapperProperty[Any]: descriptor_props = util.preloaded.orm_descriptor_props self._log( @@ -2073,6 +2075,20 @@ class Mapper( oldprop = self._props[key] self._path_registry.pop(oldprop, None) + if ( + warn_for_existing + and self.class_.__dict__.get(key, None) is not None + and not isinstance( + self._props.get(key, None), + (descriptor_props.ConcreteInheritedProperty,), + ) + ): + util.warn( + "User-placed attribute %r on %s being replaced with " + 'new property "%s"; the old attribute will be discarded' + % (self.class_.__dict__[key], self, prop) + ) + self._props[key] = prop if not self.non_primary: |