diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-01-24 16:31:01 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-01-26 17:07:42 -0500 |
commit | e84ea5bb5687ec6f6f3607565c1714b82d6647aa (patch) | |
tree | 3b5785a8015359679e87ff78195d676b084690ef /lib/sqlalchemy/orm/clsregistry.py | |
parent | 19cbf8038f4a9e8e0820bcfeb6b65bf5bc873d39 (diff) | |
download | sqlalchemy-e84ea5bb5687ec6f6f3607565c1714b82d6647aa.tar.gz |
add hooks/docs for automap w/ multiple schemas
Added new feature to :class:`.Automap` for autoload of classes across
multiple schemas which may have overlapping names, by providing both a
:paramref:`.Automap.prepare.modulename_for_class` parameter as well as a
new collection :attr:`.AutomapBase.by_module`, which stores a dot-separated
namespace of module names linked to classes.
Fixes: #5145
Change-Id: I735fecaacdfc267f1f901d76c2b3880e48f5969d
Diffstat (limited to 'lib/sqlalchemy/orm/clsregistry.py')
-rw-r--r-- | lib/sqlalchemy/orm/clsregistry.py | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/lib/sqlalchemy/orm/clsregistry.py b/lib/sqlalchemy/orm/clsregistry.py index 6734e3e7c..e5fff4a5e 100644 --- a/lib/sqlalchemy/orm/clsregistry.py +++ b/lib/sqlalchemy/orm/clsregistry.py @@ -102,7 +102,17 @@ def add_class( module = root_module.get_module(token) for token in tokens: module = module.get_module(token) - module.add_class(classname, cls) + + try: + module.add_class(classname, cls) + except AttributeError as ae: + if not isinstance(module, _ModuleMarker): + raise exc.InvalidRequestError( + f'name "{classname}" matches both a ' + "class name and a module name" + ) from ae + else: + raise def remove_class( @@ -129,7 +139,13 @@ def remove_class( module = root_module.get_module(token) for token in tokens: module = module.get_module(token) - module.remove_class(classname, cls) + try: + module.remove_class(classname, cls) + except AttributeError: + if not isinstance(module, _ModuleMarker): + pass + else: + raise def _key_is_empty( @@ -289,7 +305,16 @@ class _ModuleMarker(ClsRegistryToken): def add_class(self, name: str, cls: Type[Any]) -> None: if name in self.contents: existing = cast(_MultipleClassMarker, self.contents[name]) - existing.add_item(cls) + try: + existing.add_item(cls) + except AttributeError as ae: + if not isinstance(existing, _MultipleClassMarker): + raise exc.InvalidRequestError( + f'name "{name}" matches both a ' + "class name and a module name" + ) from ae + else: + raise else: existing = self.contents[name] = _MultipleClassMarker( [cls], on_remove=lambda: self._remove_item(name) |