在给定超类和polymorphic_identity的情况下获取多态子类

时间:2014-05-16 13:18:38

标签: python sqlalchemy

如果我有sqlalchemy多态子类,有没有办法找到给定超类和polymorphic_identity的子类?

例如:

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'employee',
        'polymorphic_on':type
    }

class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    engineer_name = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'engineer',
    }

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    manager_name = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'manager',
    }

有没有办法让工程师课程如下:

get_subclass(Employee, 'engineer')

我可以编译自己的已知子类的dict,但我希望找到一个用sqlalchemy构建的方法来实现这一点。

3 个答案:

答案 0 :(得分:1)

我的项目中有一个可以帮助你的功能

def make_class_by_discriminator_dict(module_name, root_cls=object):
    result = {}
    clss = inspect.getmembers(sys.modules[module_name], inspect.isclass)
    for _, cls in clss:
        if cls.__module__ == module_name and issubclass(cls, root_cls):
            try:
                discriminator = cls.__mapper_args__['polymorphic_identity']
                result[discriminator] = cls
            except (AttributeError, KeyError):
                pass
    return result

现在你需要的是

make_class_by_discriminator_dict(module_name, Employee)['engineer']

答案 1 :(得分:1)

基类的映射器有一个polymorphic_map属性,它将多态身份映射到各自的映射器,然后从那里就可以获得该类。所以你需要的只是:

Employee.__mapper__.polymorphic_map['engineer'].class_

答案 2 :(得分:0)

这就是我的做法。

from sqlalchemy.orm import class_mapper
mapping = {}
for mapper in class_mapper(Employee).polymorphic_iterator():
    mapping[mapper.polymorphic_identity] = mapper

...

# in a from-json function, where app_data["type"] is the discriminator
node_class = mapping[app_data["type"]].class_