Model by name in SQLAlchemy
orm, python, reflection, sqlalchemy
Solution
The resolver is not publicly accessible; the `sqlalchemy.ext.declarative._deferred_relationship` function is used, and it has a nested (hidden) `resolve_arg` function.
The function uses the following logic to resolve names:
def access_cls(key):
if key in cls._decl_class_registry:
return _GetColumns(cls._decl_class_registry[key])
elif key in cls.metadata.tables:
return cls.metadata.tables[key]
elif key in cls.metadata._schemas:
return _GetTable(key, cls.metadata)
else:
return sqlalchemy.__dict__[key]
where `cls` is a declarative class (derived from `Base`). As you can see from the code, one way to resolve a name is to use the `cls._decl_class_registry` structure, given a class `Foo`, you can resolve the string `'Blah'` to a class using `Foo._decl_class_registry['Blah']`.
The `._decl_class_registry` structure is just a python `dict`; you can also specify your own mapper when creating the `Base` class:
class_registry = {}
Base = declarative_base(class_registry=class_registry)
and then you can look up classes directly in the `class_registry` mapping.
Problem
Is it possible to get an ORM-mapped model class from name? Definitely SQLAlchemy has this functionality built-in somewhere. For instance in declarative style you can write things like `blahs = relationship('Blah')` (notice: no module prefix required). I tried looking inside `sqlalchemy.orm.properties.RelationshipProperty` but can't figure out when `argument` string is replaced by the actual thing.