Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Model by name in SQLAlchemy

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.

like image 568
julx Avatar asked Dec 16 '12 15:12

julx


1 Answers

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.

like image 174
Martijn Pieters Avatar answered Sep 25 '22 20:09

Martijn Pieters