summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/clsregistry.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2023-01-24 16:31:01 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2023-01-26 17:07:42 -0500
commite84ea5bb5687ec6f6f3607565c1714b82d6647aa (patch)
tree3b5785a8015359679e87ff78195d676b084690ef /lib/sqlalchemy/orm/clsregistry.py
parent19cbf8038f4a9e8e0820bcfeb6b65bf5bc873d39 (diff)
downloadsqlalchemy-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.py31
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)