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.

Original source